ruby_mod_kit 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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