ruby_mod_kit 0.0.2 → 0.0.3

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 (109) hide show
  1. checksums.yaml +4 -4
  2. data/lib/ruby_mod_kit/core_ext/eval.rb +6 -0
  3. data/lib/ruby_mod_kit/core_ext/load.rb +12 -4
  4. data/lib/ruby_mod_kit/core_ext.rb +2 -2
  5. data/lib/ruby_mod_kit/corrector.rb +22 -0
  6. data/lib/ruby_mod_kit/corrector_manager.rb +68 -0
  7. data/lib/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_corrector.rb +42 -0
  8. data/lib/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_mission.rb +49 -0
  9. data/lib/ruby_mod_kit/feature/instance_variable_parameter.rb +27 -0
  10. data/lib/ruby_mod_kit/feature/overload/overload_mission.rb +80 -0
  11. data/lib/ruby_mod_kit/feature/overload.rb +19 -0
  12. data/lib/ruby_mod_kit/feature/type/instance_variable_colon_corrector.rb +49 -0
  13. data/lib/ruby_mod_kit/feature/type/parameter_arrow_corrector.rb +90 -0
  14. data/lib/ruby_mod_kit/feature/type/rbs_inline/type_attr_mission.rb +41 -0
  15. data/lib/ruby_mod_kit/feature/type/rbs_inline/type_instance_variable_mission.rb +31 -0
  16. data/lib/ruby_mod_kit/feature/type/rbs_inline/type_overload_mission.rb +43 -0
  17. data/lib/ruby_mod_kit/feature/type/rbs_inline/type_parameter_mission.rb +38 -0
  18. data/lib/ruby_mod_kit/feature/type/rbs_inline/type_return_mission.rb +32 -0
  19. data/lib/ruby_mod_kit/feature/type/rbs_inline.rb +29 -0
  20. data/lib/ruby_mod_kit/feature/type/return_value_colon_corrector.rb +45 -0
  21. data/lib/ruby_mod_kit/feature/type/type_attr_mission.rb +67 -0
  22. data/lib/ruby_mod_kit/feature/type.rb +31 -0
  23. data/lib/ruby_mod_kit/feature.rb +24 -0
  24. data/lib/ruby_mod_kit/generation.rb +60 -22
  25. data/lib/ruby_mod_kit/memo/def_parent_memo.rb +36 -0
  26. data/lib/ruby_mod_kit/memo/{ivar.rb → ivar_memo.rb} +17 -3
  27. data/lib/ruby_mod_kit/memo/{method.rb → method_memo.rb} +7 -7
  28. data/lib/ruby_mod_kit/memo/offset_memo.rb +1 -1
  29. data/lib/ruby_mod_kit/memo/overload_memo.rb +46 -0
  30. data/lib/ruby_mod_kit/memo/{parameter.rb → parameter_memo.rb} +3 -3
  31. data/lib/ruby_mod_kit/memo.rb +7 -64
  32. data/lib/ruby_mod_kit/memo_pad.rb +69 -0
  33. data/lib/ruby_mod_kit/mission.rb +5 -24
  34. data/lib/ruby_mod_kit/node/base_node.rb +137 -0
  35. data/lib/ruby_mod_kit/node/call_node.rb +10 -6
  36. data/lib/ruby_mod_kit/node/def_node.rb +10 -6
  37. data/lib/ruby_mod_kit/node/def_parent_node.rb +17 -13
  38. data/lib/ruby_mod_kit/node/parameter_node.rb +12 -8
  39. data/lib/ruby_mod_kit/node/program_node.rb +2 -2
  40. data/lib/ruby_mod_kit/node/statements_node.rb +10 -6
  41. data/lib/ruby_mod_kit/node/symbol_node.rb +10 -6
  42. data/lib/ruby_mod_kit/node/untyped_node.rb +10 -6
  43. data/lib/ruby_mod_kit/node/wrap.rb +43 -0
  44. data/lib/ruby_mod_kit/node.rb +4 -148
  45. data/lib/ruby_mod_kit/version.rb +1 -1
  46. data/lib/ruby_mod_kit.rb +17 -3
  47. data/sig/generated/ruby_mod_kit/core_ext/eval.rbs +3 -0
  48. data/sig/generated/ruby_mod_kit/core_ext/load.rbs +7 -4
  49. data/sig/generated/ruby_mod_kit/corrector.rbs +16 -0
  50. data/sig/generated/ruby_mod_kit/corrector_manager.rbs +26 -0
  51. data/sig/generated/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_corrector.rbs +20 -0
  52. data/sig/generated/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_mission.rbs +21 -0
  53. data/sig/generated/ruby_mod_kit/feature/instance_variable_parameter.rbs +14 -0
  54. data/sig/generated/ruby_mod_kit/feature/overload/overload_mission.rbs +24 -0
  55. data/sig/generated/ruby_mod_kit/feature/overload.rbs +11 -0
  56. data/sig/generated/ruby_mod_kit/feature/type/instance_variable_colon_corrector.rbs +20 -0
  57. data/sig/generated/ruby_mod_kit/feature/type/parameter_arrow_corrector.rbs +39 -0
  58. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_attr_mission.rbs +19 -0
  59. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_instance_variable_mission.rbs +19 -0
  60. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_overload_mission.rbs +19 -0
  61. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_parameter_mission.rbs +19 -0
  62. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_return_mission.rbs +19 -0
  63. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline.rbs +13 -0
  64. data/sig/generated/ruby_mod_kit/feature/type/return_value_colon_corrector.rbs +20 -0
  65. data/sig/generated/ruby_mod_kit/feature/type/type_attr_mission.rbs +20 -0
  66. data/sig/generated/ruby_mod_kit/feature/type.rbs +14 -0
  67. data/sig/generated/ruby_mod_kit/feature.rbs +16 -0
  68. data/sig/generated/ruby_mod_kit/generation.rbs +25 -10
  69. data/sig/generated/ruby_mod_kit/memo/def_parent_memo.rbs +24 -0
  70. data/sig/generated/ruby_mod_kit/memo/{ivar.rbs → ivar_memo.rbs} +15 -3
  71. data/sig/generated/ruby_mod_kit/memo/{method.rbs → method_memo.rbs} +8 -8
  72. data/sig/generated/ruby_mod_kit/memo/offset_memo.rbs +1 -1
  73. data/sig/generated/ruby_mod_kit/memo/overload_memo.rbs +32 -0
  74. data/sig/generated/ruby_mod_kit/memo/{parameter.rbs → parameter_memo.rbs} +3 -3
  75. data/sig/generated/ruby_mod_kit/memo.rbs +2 -36
  76. data/sig/generated/ruby_mod_kit/memo_pad.rbs +46 -0
  77. data/sig/generated/ruby_mod_kit/mission.rbs +4 -12
  78. data/sig/generated/ruby_mod_kit/node/base_node.rbs +65 -0
  79. data/sig/generated/ruby_mod_kit/node/call_node.rbs +11 -6
  80. data/sig/generated/ruby_mod_kit/node/def_node.rbs +11 -6
  81. data/sig/generated/ruby_mod_kit/node/def_parent_node.rbs +12 -10
  82. data/sig/generated/ruby_mod_kit/node/parameter_node.rbs +13 -8
  83. data/sig/generated/ruby_mod_kit/node/program_node.rbs +2 -2
  84. data/sig/generated/ruby_mod_kit/node/statements_node.rbs +11 -6
  85. data/sig/generated/ruby_mod_kit/node/symbol_node.rbs +11 -6
  86. data/sig/generated/ruby_mod_kit/node/untyped_node.rbs +11 -6
  87. data/sig/generated/ruby_mod_kit/node/wrap.rbs +12 -0
  88. data/sig/generated/ruby_mod_kit/node.rbs +2 -58
  89. data/sig/generated/ruby_mod_kit.rbs +4 -0
  90. metadata +56 -27
  91. data/lib/ruby_mod_kit/memo/def_parent.rb +0 -27
  92. data/lib/ruby_mod_kit/mission/fix_parse_error.rb +0 -216
  93. data/lib/ruby_mod_kit/mission/ivar_arg.rb +0 -42
  94. data/lib/ruby_mod_kit/mission/overload.rb +0 -73
  95. data/lib/ruby_mod_kit/mission/type_attr.rb +0 -75
  96. data/lib/ruby_mod_kit/mission/type_parameter.rb +0 -39
  97. data/lib/ruby_mod_kit/mission/type_return.rb +0 -33
  98. data/lib/ruby_mod_kit/transpiler.rb +0 -20
  99. data/sig/generated/examples/user.rbs +0 -60
  100. data/sig/generated/ruby_mod_kit/memo/def_parent.rbs +0 -20
  101. data/sig/generated/ruby_mod_kit/memo/located.rbs +0 -14
  102. data/sig/generated/ruby_mod_kit/memo/parameter_type.rbs +0 -14
  103. data/sig/generated/ruby_mod_kit/mission/fix_parse_error.rbs +0 -73
  104. data/sig/generated/ruby_mod_kit/mission/ivar_arg.rbs +0 -19
  105. data/sig/generated/ruby_mod_kit/mission/overload.rbs +0 -20
  106. data/sig/generated/ruby_mod_kit/mission/type_attr.rbs +0 -18
  107. data/sig/generated/ruby_mod_kit/mission/type_parameter.rbs +0 -18
  108. data/sig/generated/ruby_mod_kit/mission/type_return.rbs +0 -18
  109. data/sig/generated/ruby_mod_kit/transpiler.rbs +0 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 83923be4714ddc71e6c09823f58468b46717815164235dc5437d495c62cd6b7c
4
- data.tar.gz: d7a12ed80c113de570b7a1a30c39a0f31d13803c140c1b3c1fe946ec26dde484
3
+ metadata.gz: 36509ee4c00db1106b7447ba1d4fe09ee2fd2a8f8ce763c40b1da185f19cfc61
4
+ data.tar.gz: eccbdb68bb6159aa95c7fda5d171e4089b9dfa9b262ef136caf019fa3c339d7f
5
5
  SHA512:
6
- metadata.gz: ffbd1485194583c50a78287cbb779437d1bfe8991e31e4eca113b3ec0af2d06682e42ab652bed96b7bd9edd6595116c94ffac3c34693b4575696a5ba89e48e39
7
- data.tar.gz: 8d5cd3e6989aa21225e9bdaeae4ab68658670bbbb727f5a6f965e3b5e83323a1d79b5debb79861b00fc141bb57f3630a678c5caa386583cb7a4fa0d8eefaaf79
6
+ metadata.gz: a8b12f06259193345becd29a14a1c6397481c41b390daed390cf4ed0bc7016afe0fbcf9ba95a9c3639b37150c98791d3e501cf2490725bfc5cf3c405fdc99f94
7
+ data.tar.gz: 684d9b858ac50e78b40f92a2d1cb8ddaafb99983bbdafc7788d786878af5b03c2187995bbe312de59495c9e4f796c352a9e203428d91018075a88791a79320eb
@@ -4,6 +4,7 @@
4
4
 
5
5
  require "ruby_mod_kit"
6
6
 
7
+ # Define RubyMotKit.eval
7
8
  module RubyModKit
8
9
  module CoreExt
9
10
  # the extension for eval
@@ -27,4 +28,9 @@ module RubyModKit
27
28
  end
28
29
  end
29
30
  end
31
+
32
+ class << self
33
+ include(CoreExt::Eval)
34
+ public :eval
35
+ end
30
36
  end
@@ -3,8 +3,9 @@
3
3
  # rbs_inline: enabled
4
4
 
5
5
  require "ruby_mod_kit"
6
- require "ruby_mod_kit/core_ext/eval"
6
+ require_relative "eval"
7
7
 
8
+ # Define RubyMotKit.load/require
8
9
  module RubyModKit
9
10
  module CoreExt
10
11
  # the extension for load/require
@@ -15,23 +16,25 @@ module RubyModKit
15
16
 
16
17
  # @rbs path: String
17
18
  # @rbs wrap: bool
18
- # @rbs return: void
19
+ # @rbs return: bool
19
20
  def load(path, wrap = false) # rubocop:disable Style/OptionalBooleanParameter
20
21
  return super unless path.end_with?(".rbm")
21
22
 
22
23
  b = wrap ? binding : TOPLEVEL_BINDING
23
24
  RubyModKit::CoreExt::Eval.eval(File.read(path), b, path)
25
+ true
24
26
  end
25
27
 
26
28
  # @rbs path: String
27
- # @rbs return: void
29
+ # @rbs return: bool
28
30
  def require(path)
29
31
  require_path = Load.require_path(path)
30
32
  return super unless require_path&.end_with?(".rbm")
31
- return if Load.loaded_features.include?(require_path)
33
+ return false if Load.loaded_features.include?(require_path)
32
34
 
33
35
  Load.loaded_features << require_path
34
36
  load(require_path)
37
+ true
35
38
  end
36
39
 
37
40
  class << self
@@ -63,4 +66,9 @@ module RubyModKit
63
66
  end
64
67
  end
65
68
  end
69
+
70
+ class << self
71
+ include(CoreExt::Load)
72
+ public :load, :require, :require_relative
73
+ end
66
74
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "ruby_mod_kit/core_ext/eval"
4
- require "ruby_mod_kit/core_ext/load"
3
+ require_relative "core_ext/eval"
4
+ require_relative "core_ext/load"
5
5
 
6
6
  Object.prepend(RubyModKit::CoreExt::Eval)
7
7
  Object.prepend(RubyModKit::CoreExt::Load)
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module RubyModKit
6
+ # the base class of corrector
7
+ class Corrector
8
+ # @rbs return: Array[Symbol]
9
+ def correctable_error_types
10
+ []
11
+ end
12
+
13
+ # @rbs _parse_error: Prism::ParseError
14
+ # @rbs _generation: Generation
15
+ # @rbs _root_node: Node::ProgramNode
16
+ # @rbs _memo_pad: MemoPad
17
+ # @rbs return: void
18
+ def correct(_parse_error, _generation, _root_node, _memo_pad)
19
+ raise RubyModKit::Error, "Unexpected type #{self.class}"
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module RubyModKit
6
+ # the class to manege parse error correctors
7
+ class CorrectorManager
8
+ # @rbs @previous_error_messages: Array[String]
9
+ # @rbs @correctors_error_map: Hash[Symbol, Array[Corrector]]
10
+
11
+ # @rbs features: Array[Feature]
12
+ # @rbs return: void
13
+ def initialize(features)
14
+ @previous_error_messages = []
15
+ @correctors_error_map = {}
16
+ features.each do |feature|
17
+ feature.create_correctors.each do |corrector|
18
+ corrector.correctable_error_types.each do |error_type|
19
+ (@correctors_error_map[error_type] ||= []) << corrector
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ # @rbs generation: Generation
26
+ # @rbs root_node: Node::ProgramNode
27
+ # @rbs parse_result: Prism::ParseResult
28
+ # @rbs memo_pad: MemoPad
29
+ # @rbs return: bool
30
+ def perform(generation, root_node, parse_result, memo_pad)
31
+ return true if parse_result.errors.empty?
32
+
33
+ check_prev_errors(generation, parse_result)
34
+ @previous_error_messages = parse_result.errors.map(&:message)
35
+
36
+ parse_result.errors.each do |parse_error|
37
+ correctors = @correctors_error_map[parse_error.type] || next
38
+ correctors.each do |corrector|
39
+ corrector.correct(parse_error, generation, root_node, memo_pad)
40
+ end
41
+ end
42
+
43
+ false
44
+ end
45
+
46
+ # @rbs generation: Generation
47
+ # @rbs parse_result: Prism::ParseResult
48
+ # @rbs return: void
49
+ def check_prev_errors(generation, parse_result)
50
+ return if @previous_error_messages.empty?
51
+ return if parse_result.errors.empty?
52
+ return if @previous_error_messages != parse_result.errors.map(&:message)
53
+
54
+ message = +""
55
+ parse_result.errors.each do |parse_error|
56
+ message << "\n" unless message.empty?
57
+ message << "#{generation.name}:#{parse_error.location.start_line}:#{parse_error.message} "
58
+ message << "(#{parse_error.type})"
59
+ line = parse_result.source.lines[parse_error.location.start_line - 1]
60
+ if line
61
+ message << "\n#{line.chomp}\n"
62
+ message << "#{" " * parse_error.location.start_column}^#{"~" * [parse_error.location.length - 1, 0].max}"
63
+ end
64
+ end
65
+ raise RubyModKit::SyntaxError, message
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module RubyModKit
6
+ class Feature
7
+ class InstanceVariableParameter
8
+ # the class to correct `def foo(@bar) ...` -> `def foo(bar) ...`
9
+ class InstanceVariableParameterCorrector < Corrector
10
+ # @rbs return: Array[Symbol]
11
+ def correctable_error_types
12
+ %i[argument_formal_ivar]
13
+ end
14
+
15
+ # @rbs parse_error: Prism::ParseError
16
+ # @rbs generation: Generation
17
+ # @rbs root_node: Node::ProgramNode
18
+ # @rbs memo_pad: MemoPad
19
+ # @rbs return: void
20
+ def correct(parse_error, generation, root_node, memo_pad)
21
+ src_offset = parse_error.location.start_offset
22
+
23
+ name = parse_error.location.slice[1..]
24
+ raise RubyModKit::Error unless name
25
+
26
+ parameter_position_node = root_node.node_at(src_offset)
27
+ raise RubyModKit::Error unless parameter_position_node
28
+
29
+ generation[src_offset, parse_error.location.length] = name
30
+ parameter_memo = memo_pad.parameter_memo(parameter_position_node)
31
+ parameter_memo.ivar_parameter = true
32
+
33
+ return unless parameter_memo.untyped?
34
+
35
+ def_parent_node = root_node.def_parent_node_at(parse_error.location.start_offset) || return
36
+ ivar_memo_type = memo_pad.def_parent_memo(def_parent_node).ivar_memo(name.to_sym).type || return
37
+ parameter_memo.type = ivar_memo_type
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module RubyModKit
6
+ class Feature
7
+ class InstanceVariableParameter
8
+ # The mission for instance variable arguments
9
+ class InstanceVariableParameterMission < Mission
10
+ # @rbs @assignment: String
11
+
12
+ attr_reader :assignment #: String
13
+
14
+ # @rbs generation: Generation
15
+ # @rbs root_node: Node::ProgramNode
16
+ # @rbs _parse_result: Prism::ParseResult
17
+ # @rbs memo_pad: MemoPad
18
+ # @rbs return: bool
19
+ def perform(generation, root_node, _parse_result, memo_pad)
20
+ memo_pad.parameters_memo.each_value do |parameter_memo|
21
+ next unless parameter_memo.ivar_parameter
22
+
23
+ offset = parameter_memo.offset
24
+ parameter_node = root_node.parameter_node_at(offset)
25
+ raise RubyModKit::Error unless parameter_node
26
+
27
+ def_node = root_node.def_node_at(offset)
28
+ raise RubyModKit::Error, "DefNode not found" unless def_node
29
+
30
+ def_body_location = def_node.body_location
31
+ end_loc = def_node.end_keyword_loc
32
+ if def_body_location
33
+ indent = def_body_location.start_column
34
+ src_offset = def_body_location.start_offset - indent
35
+ elsif end_loc
36
+ indent = end_loc.start_column + 2
37
+ src_offset = end_loc.start_offset - indent + 2
38
+ end
39
+ raise RubyModKit::Error if !src_offset || !indent
40
+
41
+ name = parameter_node.name
42
+ generation[src_offset, 0] = "#{" " * indent}@#{name} = #{name}\n"
43
+ end
44
+ true
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module RubyModKit
6
+ class Feature
7
+ # namespace for instance_variable parameter feature
8
+ class InstanceVariableParameter < Feature
9
+ # @rbs return: Array[Corrector]
10
+ def create_correctors
11
+ [
12
+ InstanceVariableParameterCorrector.new,
13
+ ]
14
+ end
15
+
16
+ # @rbs return: Array[Mission]
17
+ def create_missions
18
+ [
19
+ InstanceVariableParameterMission.new,
20
+ ]
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ require_relative "instance_variable_parameter/instance_variable_parameter_corrector"
27
+ require_relative "instance_variable_parameter/instance_variable_parameter_mission"
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module RubyModKit
6
+ class Feature
7
+ class Overload
8
+ # The mission for overload
9
+ class OverloadMission < Mission
10
+ # @rbs @modified: bool
11
+
12
+ OVERLOAD_METHOD_MAP = {
13
+ "*": "_mul",
14
+ }.freeze #: Hash[Symbol, String]
15
+
16
+ # @rbs return: void
17
+ def initialize
18
+ super
19
+ @modified = false
20
+ end
21
+
22
+ # @rbs generation: Generation
23
+ # @rbs root_node: Node::ProgramNode
24
+ # @rbs parse_result: Prism::ParseResult
25
+ # @rbs memo_pad: MemoPad
26
+ # @rbs return: bool
27
+ def perform(generation, root_node, parse_result, memo_pad)
28
+ return true if @modified
29
+
30
+ method_memo_groups = memo_pad.methods_memo.each_value.group_by do |method_memo|
31
+ [root_node.def_parent_node_at(method_memo.offset), method_memo.name]
32
+ end
33
+ method_memo_groups.each_value do |method_memos|
34
+ next if method_memos.length <= 1
35
+
36
+ @modified = true
37
+ first_method_memo = method_memos.first
38
+ name = first_method_memo.name
39
+ first_def_node = root_node.def_node_at(first_method_memo.offset)
40
+ raise RubyModKit::Error unless first_def_node.is_a?(Node::DefNode)
41
+ raise RubyModKit::Error unless name.is_a?(Symbol)
42
+
43
+ start_line = first_def_node.location.start_line - 1
44
+ indent = parse_result.source.lines[start_line][/\A */] || ""
45
+ src_offset = parse_result.source.offsets[start_line]
46
+ script = +""
47
+
48
+ overload_memo = memo_pad.overload_memo(first_method_memo.offset, name)
49
+
50
+ method_memos.each do |method_memo|
51
+ type = method_memo.type
52
+ type = "(#{type})" if type.include?(" ")
53
+ overload_memo.add_overload_type(method_memo.parameters.map(&:type), type)
54
+ end
55
+
56
+ script << "def #{name}(*args)\n case args\n"
57
+ overload_prefix = +"#{OVERLOAD_METHOD_MAP[name] || name}_"
58
+ method_memos.each_with_index do |method_memo, i|
59
+ overload_name = "#{overload_prefix}_overload#{i}"
60
+ def_node = root_node.def_node_at(method_memo.offset)
61
+ raise RubyModKit::Error if !def_node || !def_node.is_a?(Node::DefNode)
62
+
63
+ name_loc = def_node.name_loc
64
+ generation[name_loc.start_offset, name_loc.length] = overload_name
65
+ script << " in [#{method_memo.parameters.map(&:type).join(", ")}]\n"
66
+ script << " #{overload_name}(*args)\n"
67
+ end
68
+ script << " end\nend\n\n"
69
+
70
+ script.gsub!(/^(?=.)/, indent)
71
+ generation[src_offset, 0] = script
72
+ end
73
+
74
+ # if script has been changed, request reparsing before proceeding to the next mission
75
+ !@modified
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module RubyModKit
6
+ class Feature
7
+ # namespace for overload feature
8
+ class Overload < Feature
9
+ # @rbs return: Array[Mission]
10
+ def create_missions
11
+ [
12
+ OverloadMission.new,
13
+ ]
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ require_relative "overload/overload_mission"
@@ -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
+ # the class to correct `@var: Type` -> `# @rbs @var: Type`
9
+ class InstanceVariableColonCorrector < Corrector
10
+ # @rbs return: Array[Symbol]
11
+ def correctable_error_types
12
+ %i[unexpected_token_ignore]
13
+ end
14
+
15
+ # @rbs parse_error: Prism::ParseError
16
+ # @rbs generation: Generation
17
+ # @rbs root_node: Node::ProgramNode
18
+ # @rbs memo_pad: MemoPad
19
+ # @rbs return: void
20
+ def correct(parse_error, generation, root_node, memo_pad)
21
+ return if parse_error.location.slice != ":"
22
+
23
+ def_parent_node = root_node.statements_node_at(parse_error.location.start_offset)&.parent
24
+ return unless def_parent_node.is_a?(Node::DefParentNode)
25
+
26
+ line = generation.line(parse_error)
27
+ line_offset = generation.src_offset(parse_error) || return
28
+ attr_patterns = %i[attr_reader reader getter attr_writer writer setter attr_accessor accessor property]
29
+ return if line !~ /(\A\s*)(?:(#{attr_patterns.join("|")}) )?@(\w*)\s*:\s*(.*)\n/
30
+
31
+ length = ::Regexp.last_match(0)&.length
32
+ indent = ::Regexp.last_match(1)
33
+ attr_kind = ::Regexp.last_match(2)
34
+ ivar_name = ::Regexp.last_match(3)
35
+ type = ::Regexp.last_match(4)
36
+ return if !length || !indent || !ivar_name || !type
37
+
38
+ ivar_memo = memo_pad.def_parent_memo(def_parent_node).ivar_memo(ivar_name.to_sym)
39
+ ivar_memo.type = type
40
+ ivar_memo.offset = line_offset
41
+ ivar_memo.indent = indent
42
+ ivar_memo.attr_kind = attr_kind if attr_kind
43
+
44
+ generation[line_offset, length] = ""
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module RubyModKit
6
+ class Feature
7
+ class Type
8
+ # the class to correct `def foo(Bar => bar, *Buz => buz)` -> `def foo(bar, *buz)`
9
+ class ParameterArrowCorrector < Corrector
10
+ # @rbs return: Array[Symbol]
11
+ def correctable_error_types
12
+ %i[unexpected_token_ignore def_params_term_paren argument_formal_constant]
13
+ end
14
+
15
+ # @rbs parse_error: Prism::ParseError
16
+ # @rbs generation: Generation
17
+ # @rbs root_node: Node::ProgramNode
18
+ # @rbs memo_pad: MemoPad
19
+ # @rbs return: void
20
+ def correct(parse_error, generation, root_node, memo_pad)
21
+ case parse_error.type
22
+ when :unexpected_token_ignore
23
+ return if parse_error.location.slice != "=>"
24
+
25
+ remove_arrow_before_parameter(parse_error, generation, root_node, memo_pad)
26
+ when :def_params_term_paren
27
+ remove_arrow_after_quailifier(parse_error, generation, root_node, memo_pad)
28
+ when :argument_formal_constant
29
+ wrap_parameter_type_for_next_parse(parse_error, generation)
30
+ end
31
+ end
32
+
33
+ # @rbs parse_error: Prism::ParseError
34
+ # @rbs generation: Generation
35
+ # @rbs root_node: Node::ProgramNode
36
+ # @rbs memo_pad: MemoPad
37
+ # @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
40
+ def_parent_node = def_node.parent
41
+ parameters_node, body_node, = def_node.children
42
+ return if !def_parent_node || !parameters_node || !body_node
43
+
44
+ last_parameter_node = parameters_node.children.max_by(&:offset) || return
45
+ last_parameter_offset = last_parameter_node.offset
46
+
47
+ right_node = body_node.children.find { _1.offset >= parse_error.location.end_offset } || return
48
+ right_offset = right_node.offset
49
+ parameter_type = generation[last_parameter_offset...right_offset] || raise(RubyModKit::Error)
50
+ 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
53
+ end
54
+
55
+ # @rbs parse_error: Prism::ParseError
56
+ # @rbs generation: Generation
57
+ # @rbs root_node: Node::ProgramNode
58
+ # @rbs memo_pad: MemoPad
59
+ # @rbs return: void
60
+ def remove_arrow_after_quailifier(parse_error, generation, root_node, memo_pad)
61
+ column = parse_error.location.start_column - 1
62
+ return if column < 0
63
+
64
+ 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
68
+ offset = parse_error.location.start_offset - 1
69
+ parameter_position_node = root_node.node_at(offset + length) || return
70
+
71
+ generation[parse_error.location.start_offset, length - 1] = ""
72
+ parameter_memo = memo_pad.parameter_memo(parameter_position_node)
73
+ parameter_memo.type = type
74
+ parameter_memo.qualifier = "*"
75
+ end
76
+
77
+ # @rbs parse_error: Prism::ParseError
78
+ # @rbs generation: Generation
79
+ # @rbs return: void
80
+ def wrap_parameter_type_for_next_parse(parse_error, generation)
81
+ line = generation.line(parse_error)
82
+ line = line[parse_error.location.start_column..] || return
83
+ parameter_type = line[/(\A[A-Z]\w*(?:::[A-Z]\w*)+)(?:\s*=>\s*)/, 1] || return
84
+ src_offset = parse_error.location.start_offset
85
+ generation[src_offset, parameter_type.length] = "(#{parameter_type})"
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,41 @@
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 for parameter types
10
+ class TypeAttrMission < Mission
11
+ # @rbs generation: Generation
12
+ # @rbs root_node: Node::ProgramNode
13
+ # @rbs _parse_result: Prism::ParseResult
14
+ # @rbs memo_pad: MemoPad
15
+ # @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|
18
+ 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)
20
+ def_parent_node.body_node&.children&.each do |call_node|
21
+ break if ivars_memo.empty?
22
+ next unless call_node.is_a?(Node::CallNode)
23
+ next unless %i[attr_reader attr_writer attr_accessor].include?(call_node.name)
24
+
25
+ argument_nodes = call_node.children[0].children
26
+ next if argument_nodes.size != 1 || !argument_nodes[0].is_a?(Node::SymbolNode)
27
+
28
+ name = argument_nodes[0].value || next
29
+ ivar_memo = ivars_memo.delete(name) || next
30
+ line = generation.line(call_node)
31
+ length = line[/\A\s*(#{call_node.name}\s+:#{name})(?=\n\z)/, 1]&.length || next
32
+ generation[call_node.location.start_offset + length, 0] = " #: #{ivar_memo.type}"
33
+ end
34
+ end
35
+ true
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ 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
+ class RbsInline
9
+ # The mission for instance variable types
10
+ class TypeInstanceVariableMission < Mission
11
+ # @rbs generation: Generation
12
+ # @rbs root_node: Node::ProgramNode
13
+ # @rbs parse_result: Prism::ParseResult
14
+ # @rbs memo_pad: MemoPad
15
+ # @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|
18
+ def_parent_memo.ivars_memo.each do |name, ivar_memo|
19
+ 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"
23
+ end
24
+ end
25
+ true
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,43 @@
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 for parameter types
10
+ class TypeOverloadMission < Mission
11
+ # @rbs generation: Generation
12
+ # @rbs root_node: Node::ProgramNode
13
+ # @rbs parse_result: Prism::ParseResult
14
+ # @rbs memo_pad: MemoPad
15
+ # @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)
19
+ 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 */] || ""
23
+ offset -= indent.length
24
+
25
+ annotation = +""
26
+ overload_memo.overload_types.each do |parameter_types, return_type|
27
+ annotation << if annotation.empty?
28
+ "# @rbs"
29
+ else
30
+ "# |"
31
+ end
32
+ annotation << " (#{parameter_types.join(", ")}) -> #{return_type}\n"
33
+ end
34
+ annotation.gsub!(/^/, indent)
35
+ generation[offset, 0] = annotation
36
+ end
37
+ true
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end