ruby_mod_kit 0.0.3 → 0.0.5

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 (91) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby_mod_kit.yml +5 -0
  3. data/README.md +89 -0
  4. data/lib/ruby_mod_kit/cli.rb +17 -2
  5. data/lib/ruby_mod_kit/config.rb +53 -0
  6. data/lib/ruby_mod_kit/core_ext/eval.rb +6 -10
  7. data/lib/ruby_mod_kit/corrector.rb +4 -3
  8. data/lib/ruby_mod_kit/corrector_manager.rb +18 -18
  9. data/lib/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_corrector.rb +5 -7
  10. data/lib/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_mission.rb +4 -11
  11. data/lib/ruby_mod_kit/feature/overload/overload_mission.rb +8 -12
  12. data/lib/ruby_mod_kit/feature/type/check/arguments/add_arguments_checker_mission.rb +56 -0
  13. data/lib/ruby_mod_kit/feature/type/check/arguments.rb +23 -0
  14. data/lib/ruby_mod_kit/feature/type/instance_variable_colon_corrector.rb +20 -12
  15. data/lib/ruby_mod_kit/feature/type/parameter_arrow_corrector.rb +35 -19
  16. data/lib/ruby_mod_kit/feature/type/rbs_inline/add_magic_comment_mission.rb +49 -0
  17. data/lib/ruby_mod_kit/feature/type/rbs_inline/type_attr_mission.rb +12 -7
  18. data/lib/ruby_mod_kit/feature/type/rbs_inline/type_instance_variable_mission.rb +7 -8
  19. data/lib/ruby_mod_kit/feature/type/rbs_inline/type_overload_mission.rb +6 -9
  20. data/lib/ruby_mod_kit/feature/type/rbs_inline/type_parameter_mission.rb +9 -10
  21. data/lib/ruby_mod_kit/feature/type/rbs_inline/type_return_mission.rb +5 -7
  22. data/lib/ruby_mod_kit/feature/type/rbs_inline.rb +3 -0
  23. data/lib/ruby_mod_kit/feature/type/return_value_colon_corrector.rb +5 -6
  24. data/lib/ruby_mod_kit/feature/type/type_attr_mission.rb +13 -17
  25. data/lib/ruby_mod_kit/feature/type/yard/type_parameter_mission.rb +35 -0
  26. data/lib/ruby_mod_kit/feature/type/yard/type_return_mission.rb +30 -0
  27. data/lib/ruby_mod_kit/feature/type/yard.rb +31 -0
  28. data/lib/ruby_mod_kit/feature.rb +0 -6
  29. data/lib/ruby_mod_kit/generation.rb +83 -39
  30. data/lib/ruby_mod_kit/memo/ivar_memo.rb +4 -0
  31. data/lib/ruby_mod_kit/memo/overload_memo.rb +1 -0
  32. data/lib/ruby_mod_kit/memo/parameter_memo.rb +4 -2
  33. data/lib/ruby_mod_kit/memo.rb +0 -2
  34. data/lib/ruby_mod_kit/memo_pad.rb +9 -0
  35. data/lib/ruby_mod_kit/mission.rb +1 -8
  36. data/lib/ruby_mod_kit/node/base_node.rb +39 -12
  37. data/lib/ruby_mod_kit/node/begin_node.rb +31 -0
  38. data/lib/ruby_mod_kit/node/call_node.rb +1 -1
  39. data/lib/ruby_mod_kit/node/def_node.rb +1 -1
  40. data/lib/ruby_mod_kit/node/def_parent_node.rb +13 -6
  41. data/lib/ruby_mod_kit/node/parameter_node.rb +3 -3
  42. data/lib/ruby_mod_kit/node/program_node.rb +6 -1
  43. data/lib/ruby_mod_kit/node/statements_node.rb +1 -1
  44. data/lib/ruby_mod_kit/node/symbol_node.rb +2 -1
  45. data/lib/ruby_mod_kit/node/untyped_node.rb +1 -1
  46. data/lib/ruby_mod_kit/node/wrap.rb +3 -1
  47. data/lib/ruby_mod_kit/node.rb +1 -2
  48. data/lib/ruby_mod_kit/version.rb +1 -1
  49. data/lib/ruby_mod_kit.rb +11 -11
  50. data/ruby_mod_kit.gemspec +7 -1
  51. data/sig/generated/ruby_mod_kit/cli.rbs +5 -0
  52. data/sig/generated/ruby_mod_kit/config.rbs +21 -0
  53. data/sig/generated/ruby_mod_kit/core_ext/eval.rbs +4 -2
  54. data/sig/generated/ruby_mod_kit/corrector.rbs +4 -3
  55. data/sig/generated/ruby_mod_kit/corrector_manager.rbs +3 -7
  56. data/sig/generated/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_corrector.rbs +1 -3
  57. data/sig/generated/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_mission.rbs +1 -8
  58. data/sig/generated/ruby_mod_kit/feature/overload/overload_mission.rbs +1 -4
  59. data/sig/generated/ruby_mod_kit/feature/type/check/arguments/add_arguments_checker_mission.rbs +16 -0
  60. data/sig/generated/ruby_mod_kit/feature/type/check/arguments.rbs +15 -0
  61. data/sig/generated/ruby_mod_kit/feature/type/instance_variable_colon_corrector.rbs +7 -3
  62. data/sig/generated/ruby_mod_kit/feature/type/parameter_arrow_corrector.rbs +8 -9
  63. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/add_magic_comment_mission.rbs +21 -0
  64. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_attr_mission.rbs +1 -4
  65. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_instance_variable_mission.rbs +1 -4
  66. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_overload_mission.rbs +1 -4
  67. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_parameter_mission.rbs +1 -4
  68. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_return_mission.rbs +1 -4
  69. data/sig/generated/ruby_mod_kit/feature/type/return_value_colon_corrector.rbs +1 -3
  70. data/sig/generated/ruby_mod_kit/feature/type/type_attr_mission.rbs +3 -4
  71. data/sig/generated/ruby_mod_kit/feature/type/yard/type_parameter_mission.rbs +16 -0
  72. data/sig/generated/ruby_mod_kit/feature/type/yard/type_return_mission.rbs +16 -0
  73. data/sig/generated/ruby_mod_kit/feature/type/yard.rbs +17 -0
  74. data/sig/generated/ruby_mod_kit/feature.rbs +0 -4
  75. data/sig/generated/ruby_mod_kit/generation.rbs +55 -15
  76. data/sig/generated/ruby_mod_kit/memo/ivar_memo.rbs +8 -0
  77. data/sig/generated/ruby_mod_kit/memo/overload_memo.rbs +2 -0
  78. data/sig/generated/ruby_mod_kit/memo/parameter_memo.rbs +6 -2
  79. data/sig/generated/ruby_mod_kit/memo_pad.rbs +8 -0
  80. data/sig/generated/ruby_mod_kit/mission.rbs +1 -8
  81. data/sig/generated/ruby_mod_kit/node/base_node.rbs +22 -8
  82. data/sig/generated/ruby_mod_kit/node/begin_node.rbs +26 -0
  83. data/sig/generated/ruby_mod_kit/node/def_parent_node.rbs +5 -0
  84. data/sig/generated/ruby_mod_kit/node/parameter_node.rbs +1 -1
  85. data/sig/generated/ruby_mod_kit/node/program_node.rbs +3 -0
  86. data/sig/generated/ruby_mod_kit/node/symbol_node.rbs +2 -0
  87. data/sig/generated/ruby_mod_kit.rbs +6 -3
  88. data/sig/yaml.rbs +3 -0
  89. metadata +21 -5
  90. data/sig/generated/ruby_mod_kit/memo.rbs +0 -7
  91. data/sig/generated/ruby_mod_kit/node.rbs +0 -7
@@ -7,24 +7,30 @@ 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]
11
13
  def correctable_error_types
12
14
  %i[unexpected_token_ignore def_params_term_paren argument_formal_constant]
13
15
  end
14
16
 
17
+ # @rbs return: void
18
+ def setup
19
+ super
20
+ @last_parameter_offsets = Set.new
21
+ end
22
+
15
23
  # @rbs parse_error: Prism::ParseError
16
24
  # @rbs generation: Generation
17
- # @rbs root_node: Node::ProgramNode
18
- # @rbs memo_pad: MemoPad
19
25
  # @rbs return: void
20
- def correct(parse_error, generation, root_node, memo_pad)
26
+ def correct(parse_error, generation)
21
27
  case parse_error.type
22
28
  when :unexpected_token_ignore
23
29
  return if parse_error.location.slice != "=>"
24
30
 
25
- remove_arrow_before_parameter(parse_error, generation, root_node, memo_pad)
31
+ remove_arrow_before_parameter(parse_error, generation)
26
32
  when :def_params_term_paren
27
- remove_arrow_after_quailifier(parse_error, generation, root_node, memo_pad)
33
+ remove_arrow_after_quailifier(parse_error, generation)
28
34
  when :argument_formal_constant
29
35
  wrap_parameter_type_for_next_parse(parse_error, generation)
30
36
  end
@@ -32,45 +38,55 @@ module RubyModKit
32
38
 
33
39
  # @rbs parse_error: Prism::ParseError
34
40
  # @rbs generation: Generation
35
- # @rbs root_node: Node::ProgramNode
36
- # @rbs memo_pad: MemoPad
37
41
  # @rbs return: void
38
- def remove_arrow_before_parameter(parse_error, generation, root_node, memo_pad)
39
- def_node = root_node.def_node_at(parse_error.location.start_offset) || return
42
+ def remove_arrow_before_parameter(parse_error, generation)
43
+ def_node = generation.root_node.def_node_at(parse_error.location.start_offset) || return
40
44
  def_parent_node = def_node.parent
41
45
  parameters_node, body_node, = def_node.children
46
+ body_node = body_node.children[0] if body_node.is_a?(Node::BeginNode)
42
47
  return if !def_parent_node || !parameters_node || !body_node
43
48
 
44
49
  last_parameter_node = parameters_node.children.max_by(&:offset) || return
45
50
  last_parameter_offset = last_parameter_node.offset
51
+ return if @last_parameter_offsets.include?(last_parameter_offset)
46
52
 
53
+ @last_parameter_offsets << last_parameter_offset
47
54
  right_node = body_node.children.find { _1.offset >= parse_error.location.end_offset } || return
48
55
  right_offset = right_node.offset
56
+ name = right_node.slice[/\A\w+/]
49
57
  parameter_type = generation[last_parameter_offset...right_offset] || raise(RubyModKit::Error)
50
58
  parameter_type = parameter_type.sub(/\s*=>\s*\z/, "")
51
- generation[last_parameter_offset, right_offset - last_parameter_offset] = ""
52
- memo_pad.parameter_memo(last_parameter_node).type = parameter_type
59
+ qualifier = nil
60
+ parameter_type = parameter_type.sub(/\A&\(\((.*)\) *: +(.*)\)\z/) do
61
+ qualifier = "&"
62
+ "(#{::Regexp.last_match(1)}) -> #{::Regexp.last_match(2)}"
63
+ end
64
+ generation[last_parameter_offset, right_offset - last_parameter_offset] = qualifier.to_s
65
+ parameter_memo = generation.memo_pad.parameter_memo(last_parameter_node)
66
+ parameter_memo.name = name.to_sym if name
67
+ parameter_memo.type = parameter_type
68
+ parameter_memo.qualifier = qualifier if qualifier
53
69
  end
54
70
 
55
71
  # @rbs parse_error: Prism::ParseError
56
72
  # @rbs generation: Generation
57
- # @rbs root_node: Node::ProgramNode
58
- # @rbs memo_pad: MemoPad
59
73
  # @rbs return: void
60
- def remove_arrow_after_quailifier(parse_error, generation, root_node, memo_pad)
74
+ def remove_arrow_after_quailifier(parse_error, generation)
61
75
  column = parse_error.location.start_column - 1
62
76
  return if column < 0
63
77
 
64
78
  line = generation.line(parse_error)[column..] || return
65
- line =~ /\A\*(.*?)\s*=>\s*/
66
- length = ::Regexp.last_match(0)&.length || return
67
- type = ::Regexp.last_match(1) || return
79
+ line =~ /(\A\*(.*?)\s*=>\s*)(\w*)/
80
+ length = ::Regexp.last_match(1)&.length || return
81
+ type = ::Regexp.last_match(2) || return
82
+ name = ::Regexp.last_match(3)
68
83
  offset = parse_error.location.start_offset - 1
69
- parameter_position_node = root_node.node_at(offset + length) || return
84
+ parameter_position_node = generation.root_node.node_at(offset + length) || return
70
85
 
71
86
  generation[parse_error.location.start_offset, length - 1] = ""
72
- parameter_memo = memo_pad.parameter_memo(parameter_position_node)
87
+ parameter_memo = generation.memo_pad.parameter_memo(parameter_position_node)
73
88
  parameter_memo.type = type
89
+ parameter_memo.name = name.to_sym if name
74
90
  parameter_memo.qualifier = "*"
75
91
  end
76
92
 
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module RubyModKit
6
+ class Feature
7
+ class Type
8
+ class RbsInline
9
+ # The mission to add magic comment
10
+ class AddMagicCommentMission < Mission
11
+ # @rbs @reloaded: bool
12
+
13
+ # @rbs return: void
14
+ def initialize
15
+ super
16
+ @reloaded = false
17
+ end
18
+
19
+ # @rbs generation: Generation
20
+ # @rbs return: bool
21
+ def perform(generation)
22
+ return true unless generation.memo_pad.flags[:rbs_annotated]
23
+
24
+ unless @reloaded
25
+ @reloaded = true
26
+ return false
27
+ end
28
+
29
+ offset = 0
30
+ separated = false
31
+ generation.lines.each do |line|
32
+ break if line =~ /^# @rbs/
33
+ break if line !~ /^#( rbs_inline: enabled)?|(^$)/
34
+ return true if ::Regexp.last_match(1)
35
+
36
+ separated = !::Regexp.last_match(2).nil?
37
+
38
+ offset += line.length
39
+ end
40
+ script = +""
41
+ script << "\n" unless separated
42
+ generation[offset, 0] = "# rbs_inline: enabled\n\n"
43
+ true
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -9,16 +9,20 @@ module RubyModKit
9
9
  # The mission for parameter types
10
10
  class TypeAttrMission < Mission
11
11
  # @rbs generation: Generation
12
- # @rbs root_node: Node::ProgramNode
13
- # @rbs _parse_result: Prism::ParseResult
14
- # @rbs memo_pad: MemoPad
15
12
  # @rbs return: bool
16
- def perform(generation, root_node, _parse_result, memo_pad)
17
- memo_pad.def_parents_memo.each_value do |def_parent_memo|
13
+ def perform(generation)
14
+ generation.memo_pad.def_parents_memo.each_value do |def_parent_memo|
18
15
  ivars_memo = def_parent_memo.ivars_memo.dup
19
- def_parent_node = root_node.def_parent_node_at(def_parent_memo.offset) || raise(RubyModKit::Error)
16
+ def_parent_node = generation.root_node.def_parent_node_at(def_parent_memo.offset)
17
+ raise(RubyModKit::Error) unless def_parent_node
18
+
20
19
  def_parent_node.body_node&.children&.each do |call_node|
21
20
  break if ivars_memo.empty?
21
+
22
+ if call_node.is_a?(Node::CallNode) && %i[public private protected].include?(call_node.name)
23
+ call_node = call_node.children[0]
24
+ call_node = call_node.children[0] if call_node
25
+ end
22
26
  next unless call_node.is_a?(Node::CallNode)
23
27
  next unless %i[attr_reader attr_writer attr_accessor].include?(call_node.name)
24
28
 
@@ -28,7 +32,8 @@ module RubyModKit
28
32
  name = argument_nodes[0].value || next
29
33
  ivar_memo = ivars_memo.delete(name) || next
30
34
  line = generation.line(call_node)
31
- length = line[/\A\s*(#{call_node.name}\s+:#{name})(?=\n\z)/, 1]&.length || next
35
+ length = line[/\A.*(#{call_node.name}\s+:#{name})(?=\n\z)/, 1]&.length || next
36
+ generation.memo_pad.flags[:rbs_annotated] = true
32
37
  generation[call_node.location.start_offset + length, 0] = " #: #{ivar_memo.type}"
33
38
  end
34
39
  end
@@ -9,17 +9,16 @@ module RubyModKit
9
9
  # The mission for instance variable types
10
10
  class TypeInstanceVariableMission < Mission
11
11
  # @rbs generation: Generation
12
- # @rbs root_node: Node::ProgramNode
13
- # @rbs parse_result: Prism::ParseResult
14
- # @rbs memo_pad: MemoPad
15
12
  # @rbs return: bool
16
- def perform(generation, root_node, parse_result, memo_pad)
17
- memo_pad.def_parents_memo.each_value do |def_parent_memo|
13
+ def perform(generation)
14
+ generation.memo_pad.def_parents_memo.each_value do |def_parent_memo|
18
15
  def_parent_memo.ivars_memo.each do |name, ivar_memo|
19
16
  offset = ivar_memo.offset || next
20
- def_parent_node = root_node.def_parent_node_at(offset) || next
21
- body_line_offset = parse_result.source.offsets[def_parent_node.prism_node.location.start_line]
22
- generation[body_line_offset, 0] = "#{ivar_memo.indent}# @rbs @#{name}: #{ivar_memo.type}\n"
17
+ def_parent_node = generation.root_node.def_parent_node_at(offset) || next
18
+ body_line_offset = generation.line_offset(def_parent_node, 1) || next
19
+ generation.memo_pad.flags[:rbs_annotated] = true
20
+ script = "#{ivar_memo.indent}# @rbs @#{name}: #{ivar_memo.type}\n#{ivar_memo.separator}"
21
+ generation[body_line_offset, 0] = script
23
22
  end
24
23
  end
25
24
  true
@@ -9,17 +9,13 @@ module RubyModKit
9
9
  # The mission for parameter types
10
10
  class TypeOverloadMission < Mission
11
11
  # @rbs generation: Generation
12
- # @rbs root_node: Node::ProgramNode
13
- # @rbs parse_result: Prism::ParseResult
14
- # @rbs memo_pad: MemoPad
15
12
  # @rbs return: bool
16
- def perform(generation, root_node, parse_result, memo_pad)
17
- memo_pad.overloads_memo.each_value do |overload_memo|
18
- overload_memo.correct_offset(root_node)
13
+ def perform(generation)
14
+ generation.memo_pad.overloads_memo.each_value do |overload_memo|
15
+ overload_memo.correct_offset(generation.root_node)
19
16
  offset = overload_memo.offset
20
- def_node = root_node.def_node_at(offset) || raise(RubyModKit::Error)
21
- start_line = def_node.location.start_line - 1
22
- indent = parse_result.source.lines[start_line][/\A */] || ""
17
+ def_node = generation.root_node.def_node_at(offset) || raise(RubyModKit::Error)
18
+ indent = generation.line_indent(def_node)
23
19
  offset -= indent.length
24
20
 
25
21
  annotation = +""
@@ -32,6 +28,7 @@ module RubyModKit
32
28
  annotation << " (#{parameter_types.join(", ")}) -> #{return_type}\n"
33
29
  end
34
30
  annotation.gsub!(/^/, indent)
31
+ generation.memo_pad.flags[:rbs_annotated] = true
35
32
  generation[offset, 0] = annotation
36
33
  end
37
34
  true
@@ -9,25 +9,24 @@ module RubyModKit
9
9
  # The mission for parameter types
10
10
  class TypeParameterMission < Mission
11
11
  # @rbs generation: Generation
12
- # @rbs root_node: Node::ProgramNode
13
- # @rbs parse_result: Prism::ParseResult
14
- # @rbs memo_pad: MemoPad
15
12
  # @rbs return: bool
16
- def perform(generation, root_node, parse_result, memo_pad)
17
- memo_pad.parameters_memo.each do |offset, parameter_memo|
13
+ def perform(generation)
14
+ generation.memo_pad.each_parameter_memo do |parameter_memo|
18
15
  next if parameter_memo.untyped?
19
16
 
20
- def_node = root_node.def_node_at(offset)
17
+ offset = parameter_memo.offset
18
+ def_node = generation.root_node.def_node_at(offset)
21
19
  raise RubyModKit::Error, "DefNode not found" if !def_node || !def_node.is_a?(Node::DefNode)
22
20
 
23
- parameter_node = root_node.parameter_node_at(offset)
21
+ parameter_node = generation.root_node.parameter_node_at(offset)
24
22
  raise RubyModKit::Error, "ParameterNode not found" unless parameter_node
25
23
 
24
+ line_offset = generation.line_offset(def_node) || raise(RubyModKit::Error)
26
25
  type = parameter_memo.type
27
- src_offset = parse_result.source.offsets[def_node.location.start_line - 1]
28
- indent = def_node.offset - src_offset
26
+ indent = generation.line_indent(def_node)
29
27
  qualified_name = "#{parameter_memo.qualifier}#{parameter_node.name}"
30
- generation[src_offset, 0] = "#{" " * indent}# @rbs #{qualified_name}: #{type}\n"
28
+ generation.memo_pad.flags[:rbs_annotated] = true
29
+ generation[line_offset, 0] = "#{indent}# @rbs #{qualified_name}: #{type}\n"
31
30
  end
32
31
  true
33
32
  end
@@ -9,18 +9,16 @@ module RubyModKit
9
9
  # The mission for parameter types
10
10
  class TypeReturnMission < Mission
11
11
  # @rbs generation: Generation
12
- # @rbs root_node: Node::ProgramNode
13
- # @rbs parse_result: Prism::ParseResult
14
- # @rbs memo_pad: MemoPad
15
12
  # @rbs return: bool
16
- def perform(generation, root_node, parse_result, memo_pad)
17
- memo_pad.methods_memo.each do |offset, method_memo|
18
- def_node = root_node.def_node_at(offset)
13
+ def perform(generation)
14
+ generation.memo_pad.methods_memo.each do |offset, method_memo|
15
+ def_node = generation.root_node.def_node_at(offset)
19
16
  raise RubyModKit::Error, "DefNode not found" if !def_node || !def_node.is_a?(Node::DefNode)
20
17
  next if method_memo.untyped?
21
18
 
22
- src_offset = parse_result.source.offsets[def_node.location.start_line - 1]
19
+ src_offset = generation.line_offset(def_node) || raise(RubyModKit::Error)
23
20
  indent = offset - src_offset
21
+ generation.memo_pad.flags[:rbs_annotated] = true
24
22
  generation[src_offset, 0] = "#{" " * indent}# @rbs return: #{method_memo.type}\n"
25
23
  end
26
24
  true
@@ -15,6 +15,8 @@ module RubyModKit
15
15
  TypeOverloadMission.new,
16
16
  TypeParameterMission.new,
17
17
  TypeReturnMission.new,
18
+ # This mission must be the last
19
+ AddMagicCommentMission.new,
18
20
  ]
19
21
  end
20
22
  end
@@ -22,6 +24,7 @@ module RubyModKit
22
24
  end
23
25
  end
24
26
 
27
+ require_relative "rbs_inline/add_magic_comment_mission"
25
28
  require_relative "rbs_inline/type_attr_mission"
26
29
  require_relative "rbs_inline/type_instance_variable_mission"
27
30
  require_relative "rbs_inline/type_overload_mission"
@@ -14,13 +14,12 @@ module RubyModKit
14
14
 
15
15
  # @rbs parse_error: Prism::ParseError
16
16
  # @rbs generation: Generation
17
- # @rbs root_node: Node::ProgramNode
18
- # @rbs memo_pad: MemoPad
19
17
  # @rbs return: void
20
- def correct(parse_error, generation, root_node, memo_pad)
18
+ def correct(parse_error, generation)
21
19
  return if parse_error.location.slice != ":"
22
20
 
23
- def_node = root_node.statements_node_at(parse_error.location.start_offset)&.parent
21
+ def_node = generation.root_node.statements_node_at(parse_error.location.start_offset)&.parent
22
+ def_node = def_node.parent if def_node.is_a?(Node::BeginNode)
24
23
  return unless def_node.is_a?(Node::DefNode)
25
24
 
26
25
  lparen_loc = def_node.lparen_loc
@@ -34,10 +33,10 @@ module RubyModKit
34
33
  end
35
34
  return if generation[src_offset...parse_error.location.start_offset] !~ /\A\s*\z/
36
35
 
37
- right_node = root_node.node_at(parse_error.location.end_offset + 1)
36
+ right_node = generation.root_node.node_at(parse_error.location.end_offset + 1)
38
37
  return_type_location = right_node&.location || return_type_location
39
38
  generation[src_offset, return_type_location.end_offset - src_offset] = ""
40
- memo_pad.method_memo(def_node).type = return_type_location.slice
39
+ generation.memo_pad.method_memo(def_node).type = return_type_location.slice
41
40
  end
42
41
  end
43
42
  end
@@ -7,6 +7,8 @@ module RubyModKit
7
7
  class Type
8
8
  # The mission for parameter attributes
9
9
  class TypeAttrMission < Mission
10
+ # @rbs @modified: bool
11
+
10
12
  # @rbs return: void
11
13
  def initialize
12
14
  super
@@ -14,34 +16,26 @@ module RubyModKit
14
16
  end
15
17
 
16
18
  # @rbs generation: Generation
17
- # @rbs root_node: Node::ProgramNode
18
- # @rbs _parse_result: Prism::ParseResult
19
- # @rbs memo_pad: MemoPad
20
19
  # @rbs return: bool
21
- def perform(generation, root_node, _parse_result, memo_pad)
20
+ def perform(generation)
22
21
  return true if @modified
23
22
 
24
- memo_pad.def_parents_memo.each_value do |def_parent_memo|
25
- ivars_memo = def_parent_memo.ivars_memo.dup
26
- def_parent_node = root_node.def_parent_node_at(def_parent_memo.offset) || raise(RubyModKit::Error)
23
+ generation.memo_pad.def_parents_memo.each_value do |def_parent_memo|
27
24
  attr_adding_line = 0
25
+ ivars_memo = def_parent_memo.ivars_memo.dup
26
+ def_parent_node = generation.root_node.def_parent_node_at(def_parent_memo.offset)
27
+ raise(RubyModKit::Error) unless def_parent_node
28
28
 
29
29
  ivars_memo.keep_if { |_, ivar_memo| ivar_memo.attr_kind }
30
30
  next if ivars_memo.empty?
31
31
 
32
- add_first_separator_line = false
33
32
  if attr_adding_line == 0
34
33
  attr_adding_line = def_parent_node.location.start_line
35
- prev_line = nil
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 != ""
34
+ attr_adding_line += 1 while generation.line(attr_adding_line) =~ /\A\s*#.*|\A$/
41
35
  end
42
36
  line = generation.line(attr_adding_line) || next
43
37
  add_separator_line = line != "\n" && line !~ /\A\s*end$/
44
- offset = generation.src_offset(attr_adding_line) || next
38
+ offset = generation.line_offset(attr_adding_line) || next
45
39
 
46
40
  body_node = def_parent_node.body_node
47
41
  if body_node
@@ -50,11 +44,13 @@ module RubyModKit
50
44
  else
51
45
  def_parent_line = generation.line(def_parent_node)
52
46
  indent = " #{def_parent_line[/\A\s*/]}"
47
+ generation[offset, 0] = "\n"
53
48
  end
54
49
 
55
- generation[offset, 0] = "\n" if add_first_separator_line
56
50
  ivars_memo.each do |name, ivar_memo|
57
- generation[offset, 0] = "#{indent}#{ivar_memo.attr_kind} :#{name}\n"
51
+ attr = ivar_memo.attr_kind
52
+ attr = "#{ivar_memo.visibility} #{attr}" if ivar_memo.visibility
53
+ generation[offset, 0] = "#{indent}#{attr} :#{name}\n"
58
54
  end
59
55
  @modified = true
60
56
  generation[offset, 0] = "\n" if add_separator_line
@@ -0,0 +1,35 @@
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
+ def perform(generation)
14
+ generation.memo_pad.each_parameter_memo do |parameter_memo|
15
+ next if parameter_memo.untyped?
16
+
17
+ offset = parameter_memo.offset
18
+ def_node = generation.root_node.def_node_at(offset)
19
+ raise RubyModKit::Error, "DefNode not found" if !def_node || !def_node.is_a?(Node::DefNode)
20
+
21
+ parameter_node = generation.root_node.parameter_node_at(offset)
22
+ raise RubyModKit::Error, "ParameterNode not found" unless parameter_node
23
+
24
+ line_offset = generation.line_offset(def_node) || raise(RubyModKit::Error)
25
+ indent = generation.line_indent(def_node)
26
+ script = "#{indent}# @param #{parameter_node.name} [#{Yard.rbs2yard(parameter_memo.type)}]\n"
27
+ generation[line_offset, 0] = script
28
+ end
29
+ true
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,30 @@
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
+ def perform(generation)
14
+ generation.memo_pad.methods_memo.each do |offset, method_memo|
15
+ def_node = generation.root_node.def_node_at(offset)
16
+ raise RubyModKit::Error, "DefNode not found" if !def_node || !def_node.is_a?(Node::DefNode)
17
+ next if method_memo.untyped?
18
+
19
+ src_offset = generation.line_offset(def_node) || raise(RubyModKit::Error)
20
+ indent = offset - src_offset
21
+ generation.memo_pad.flags[:rbs_annotated] = true
22
+ generation[src_offset, 0] = "#{" " * indent}# @return [#{Yard.rbs2yard(method_memo.type)}]\n"
23
+ end
24
+ true
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,31 @@
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
+ def create_missions
12
+ [
13
+ TypeParameterMission.new,
14
+ TypeReturnMission.new,
15
+ ]
16
+ end
17
+
18
+ class << self
19
+ # @rbs type: String
20
+ # @rbs return: String
21
+ def rbs2yard(type)
22
+ type.gsub(/\s*\|\s*/, ", ").tr("[]", "<>").gsub(/(?<=^|\W)bool(?=$|\W)/, "Boolean")
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ require_relative "yard/type_parameter_mission"
31
+ require_relative "yard/type_return_mission"
@@ -5,12 +5,6 @@
5
5
  module RubyModKit
6
6
  # the base class of feature
7
7
  class Feature
8
- # @rbs other: Feature
9
- # @rbs return: -1 | 0 | 1 | nil
10
- def <=>(other)
11
- self.class.name <=> other.class.name
12
- end
13
-
14
8
  # @rbs return: Array[Corrector]
15
9
  def create_correctors
16
10
  []