ruby_mod_kit 0.0.2 → 0.0.4

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 (118) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby_mod_kit.yml +5 -0
  3. data/lib/ruby_mod_kit/cli.rb +17 -2
  4. data/lib/ruby_mod_kit/config.rb +53 -0
  5. data/lib/ruby_mod_kit/core_ext/eval.rb +6 -0
  6. data/lib/ruby_mod_kit/core_ext/load.rb +12 -4
  7. data/lib/ruby_mod_kit/core_ext.rb +2 -2
  8. data/lib/ruby_mod_kit/corrector.rb +20 -0
  9. data/lib/ruby_mod_kit/corrector_manager.rb +64 -0
  10. data/lib/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_corrector.rb +40 -0
  11. data/lib/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_mission.rb +42 -0
  12. data/lib/ruby_mod_kit/feature/instance_variable_parameter.rb +27 -0
  13. data/lib/ruby_mod_kit/feature/overload/overload_mission.rb +77 -0
  14. data/lib/ruby_mod_kit/feature/overload.rb +19 -0
  15. data/lib/ruby_mod_kit/feature/type/instance_variable_colon_corrector.rb +52 -0
  16. data/lib/ruby_mod_kit/feature/type/parameter_arrow_corrector.rb +84 -0
  17. data/lib/ruby_mod_kit/feature/type/rbs_inline/add_magic_comment_mission.rb +49 -0
  18. data/lib/ruby_mod_kit/feature/type/rbs_inline/type_attr_mission.rb +46 -0
  19. data/lib/ruby_mod_kit/feature/type/rbs_inline/type_instance_variable_mission.rb +29 -0
  20. data/lib/ruby_mod_kit/feature/type/rbs_inline/type_overload_mission.rb +41 -0
  21. data/lib/ruby_mod_kit/feature/type/rbs_inline/type_parameter_mission.rb +36 -0
  22. data/lib/ruby_mod_kit/feature/type/rbs_inline/type_return_mission.rb +30 -0
  23. data/lib/ruby_mod_kit/feature/type/rbs_inline.rb +32 -0
  24. data/lib/ruby_mod_kit/feature/type/return_value_colon_corrector.rb +43 -0
  25. data/lib/ruby_mod_kit/feature/type/type_attr_mission.rb +69 -0
  26. data/lib/ruby_mod_kit/feature/type.rb +31 -0
  27. data/lib/ruby_mod_kit/feature.rb +18 -0
  28. data/lib/ruby_mod_kit/generation.rb +76 -29
  29. data/lib/ruby_mod_kit/memo/def_parent_memo.rb +36 -0
  30. data/lib/ruby_mod_kit/memo/{ivar.rb → ivar_memo.rb} +19 -3
  31. data/lib/ruby_mod_kit/memo/{method.rb → method_memo.rb} +7 -7
  32. data/lib/ruby_mod_kit/memo/offset_memo.rb +1 -1
  33. data/lib/ruby_mod_kit/memo/overload_memo.rb +47 -0
  34. data/lib/ruby_mod_kit/memo/{parameter.rb → parameter_memo.rb} +3 -3
  35. data/lib/ruby_mod_kit/memo.rb +7 -66
  36. data/lib/ruby_mod_kit/memo_pad.rb +72 -0
  37. data/lib/ruby_mod_kit/mission.rb +3 -25
  38. data/lib/ruby_mod_kit/node/base_node.rb +155 -0
  39. data/lib/ruby_mod_kit/node/call_node.rb +11 -7
  40. data/lib/ruby_mod_kit/node/def_node.rb +11 -7
  41. data/lib/ruby_mod_kit/node/def_parent_node.rb +25 -14
  42. data/lib/ruby_mod_kit/node/parameter_node.rb +13 -9
  43. data/lib/ruby_mod_kit/node/program_node.rb +8 -3
  44. data/lib/ruby_mod_kit/node/statements_node.rb +11 -7
  45. data/lib/ruby_mod_kit/node/symbol_node.rb +12 -7
  46. data/lib/ruby_mod_kit/node/untyped_node.rb +11 -7
  47. data/lib/ruby_mod_kit/node/wrap.rb +43 -0
  48. data/lib/ruby_mod_kit/node.rb +4 -150
  49. data/lib/ruby_mod_kit/version.rb +1 -1
  50. data/lib/ruby_mod_kit.rb +27 -8
  51. data/ruby_mod_kit.gemspec +7 -1
  52. data/sig/generated/ruby_mod_kit/cli.rbs +5 -0
  53. data/sig/generated/ruby_mod_kit/config.rbs +21 -0
  54. data/sig/generated/ruby_mod_kit/core_ext/eval.rbs +3 -0
  55. data/sig/generated/ruby_mod_kit/core_ext/load.rbs +7 -4
  56. data/sig/generated/ruby_mod_kit/corrector.rbs +14 -0
  57. data/sig/generated/ruby_mod_kit/corrector_manager.rbs +22 -0
  58. data/sig/generated/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_corrector.rbs +18 -0
  59. data/sig/generated/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_mission.rbs +14 -0
  60. data/sig/generated/ruby_mod_kit/feature/instance_variable_parameter.rbs +14 -0
  61. data/sig/generated/ruby_mod_kit/feature/overload/overload_mission.rbs +21 -0
  62. data/sig/generated/ruby_mod_kit/feature/overload.rbs +11 -0
  63. data/sig/generated/ruby_mod_kit/feature/type/instance_variable_colon_corrector.rbs +24 -0
  64. data/sig/generated/ruby_mod_kit/feature/type/parameter_arrow_corrector.rbs +33 -0
  65. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/add_magic_comment_mission.rbs +21 -0
  66. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_attr_mission.rbs +16 -0
  67. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_instance_variable_mission.rbs +16 -0
  68. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_overload_mission.rbs +16 -0
  69. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_parameter_mission.rbs +16 -0
  70. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_return_mission.rbs +16 -0
  71. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline.rbs +13 -0
  72. data/sig/generated/ruby_mod_kit/feature/type/return_value_colon_corrector.rbs +18 -0
  73. data/sig/generated/ruby_mod_kit/feature/type/type_attr_mission.rbs +19 -0
  74. data/sig/generated/ruby_mod_kit/feature/type.rbs +14 -0
  75. data/sig/generated/ruby_mod_kit/feature.rbs +12 -0
  76. data/sig/generated/ruby_mod_kit/generation.rbs +44 -13
  77. data/sig/generated/ruby_mod_kit/memo/def_parent_memo.rbs +24 -0
  78. data/sig/generated/ruby_mod_kit/memo/{ivar.rbs → ivar_memo.rbs} +19 -3
  79. data/sig/generated/ruby_mod_kit/memo/{method.rbs → method_memo.rbs} +8 -8
  80. data/sig/generated/ruby_mod_kit/memo/offset_memo.rbs +1 -1
  81. data/sig/generated/ruby_mod_kit/memo/overload_memo.rbs +34 -0
  82. data/sig/generated/ruby_mod_kit/memo/{parameter.rbs → parameter_memo.rbs} +3 -3
  83. data/sig/generated/ruby_mod_kit/memo_pad.rbs +50 -0
  84. data/sig/generated/ruby_mod_kit/mission.rbs +2 -13
  85. data/sig/generated/ruby_mod_kit/node/base_node.rbs +75 -0
  86. data/sig/generated/ruby_mod_kit/node/call_node.rbs +11 -6
  87. data/sig/generated/ruby_mod_kit/node/def_node.rbs +11 -6
  88. data/sig/generated/ruby_mod_kit/node/def_parent_node.rbs +17 -10
  89. data/sig/generated/ruby_mod_kit/node/parameter_node.rbs +13 -8
  90. data/sig/generated/ruby_mod_kit/node/program_node.rbs +5 -2
  91. data/sig/generated/ruby_mod_kit/node/statements_node.rbs +11 -6
  92. data/sig/generated/ruby_mod_kit/node/symbol_node.rbs +13 -6
  93. data/sig/generated/ruby_mod_kit/node/untyped_node.rbs +11 -6
  94. data/sig/generated/ruby_mod_kit/node/wrap.rbs +12 -0
  95. data/sig/generated/ruby_mod_kit.rbs +10 -3
  96. data/sig/yaml.rbs +3 -0
  97. metadata +63 -30
  98. data/lib/ruby_mod_kit/memo/def_parent.rb +0 -27
  99. data/lib/ruby_mod_kit/mission/fix_parse_error.rb +0 -216
  100. data/lib/ruby_mod_kit/mission/ivar_arg.rb +0 -42
  101. data/lib/ruby_mod_kit/mission/overload.rb +0 -73
  102. data/lib/ruby_mod_kit/mission/type_attr.rb +0 -75
  103. data/lib/ruby_mod_kit/mission/type_parameter.rb +0 -39
  104. data/lib/ruby_mod_kit/mission/type_return.rb +0 -33
  105. data/lib/ruby_mod_kit/transpiler.rb +0 -20
  106. data/sig/generated/examples/user.rbs +0 -60
  107. data/sig/generated/ruby_mod_kit/memo/def_parent.rbs +0 -20
  108. data/sig/generated/ruby_mod_kit/memo/located.rbs +0 -14
  109. data/sig/generated/ruby_mod_kit/memo/parameter_type.rbs +0 -14
  110. data/sig/generated/ruby_mod_kit/memo.rbs +0 -41
  111. data/sig/generated/ruby_mod_kit/mission/fix_parse_error.rbs +0 -73
  112. data/sig/generated/ruby_mod_kit/mission/ivar_arg.rbs +0 -19
  113. data/sig/generated/ruby_mod_kit/mission/overload.rbs +0 -20
  114. data/sig/generated/ruby_mod_kit/mission/type_attr.rbs +0 -18
  115. data/sig/generated/ruby_mod_kit/mission/type_parameter.rbs +0 -18
  116. data/sig/generated/ruby_mod_kit/mission/type_return.rbs +0 -18
  117. data/sig/generated/ruby_mod_kit/node.rbs +0 -63
  118. data/sig/generated/ruby_mod_kit/transpiler.rbs +0 -11
@@ -0,0 +1,46 @@
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 return: bool
13
+ def perform(generation)
14
+ generation.memo_pad.def_parents_memo.each_value do |def_parent_memo|
15
+ ivars_memo = def_parent_memo.ivars_memo.dup
16
+ def_parent_node = generation.root_node.def_parent_node_at(def_parent_memo.offset)
17
+ raise(RubyModKit::Error) unless def_parent_node
18
+
19
+ def_parent_node.body_node&.children&.each do |call_node|
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
26
+ next unless call_node.is_a?(Node::CallNode)
27
+ next unless %i[attr_reader attr_writer attr_accessor].include?(call_node.name)
28
+
29
+ argument_nodes = call_node.children[0].children
30
+ next if argument_nodes.size != 1 || !argument_nodes[0].is_a?(Node::SymbolNode)
31
+
32
+ name = argument_nodes[0].value || next
33
+ ivar_memo = ivars_memo.delete(name) || next
34
+ line = generation.line(call_node)
35
+ length = line[/\A.*(#{call_node.name}\s+:#{name})(?=\n\z)/, 1]&.length || next
36
+ generation.memo_pad.flags[:rbs_annotated] = true
37
+ generation[call_node.location.start_offset + length, 0] = " #: #{ivar_memo.type}"
38
+ end
39
+ end
40
+ true
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,29 @@
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 return: bool
13
+ def perform(generation)
14
+ generation.memo_pad.def_parents_memo.each_value do |def_parent_memo|
15
+ def_parent_memo.ivars_memo.each do |name, ivar_memo|
16
+ offset = ivar_memo.offset || next
17
+ def_parent_node = generation.root_node.def_parent_node_at(offset) || next
18
+ body_line_offset = generation.offsets[def_parent_node.location.start_line]
19
+ generation.memo_pad.flags[:rbs_annotated] = true
20
+ generation[body_line_offset, 0] = "#{ivar_memo.indent}# @rbs @#{name}: #{ivar_memo.type}\n"
21
+ end
22
+ end
23
+ true
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ 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 TypeOverloadMission < Mission
11
+ # @rbs generation: Generation
12
+ # @rbs return: bool
13
+ def perform(generation)
14
+ generation.memo_pad.overloads_memo.each_value do |overload_memo|
15
+ overload_memo.correct_offset(generation.root_node)
16
+ offset = overload_memo.offset
17
+ def_node = generation.root_node.def_node_at(offset) || raise(RubyModKit::Error)
18
+ start_line = def_node.location.start_line - 1
19
+ indent = generation.lines[start_line][/\A */] || ""
20
+ offset -= indent.length
21
+
22
+ annotation = +""
23
+ overload_memo.overload_types.each do |parameter_types, return_type|
24
+ annotation << if annotation.empty?
25
+ "# @rbs"
26
+ else
27
+ "# |"
28
+ end
29
+ annotation << " (#{parameter_types.join(", ")}) -> #{return_type}\n"
30
+ end
31
+ annotation.gsub!(/^/, indent)
32
+ generation.memo_pad.flags[:rbs_annotated] = true
33
+ generation[offset, 0] = annotation
34
+ end
35
+ true
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,36 @@
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 TypeParameterMission < Mission
11
+ # @rbs generation: Generation
12
+ # @rbs return: bool
13
+ def perform(generation)
14
+ generation.memo_pad.parameters_memo.each do |offset, parameter_memo|
15
+ next if parameter_memo.untyped?
16
+
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
+
20
+ parameter_node = generation.root_node.parameter_node_at(offset)
21
+ raise RubyModKit::Error, "ParameterNode not found" unless parameter_node
22
+
23
+ type = parameter_memo.type
24
+ src_offset = generation.offsets[def_node.location.start_line - 1]
25
+ indent = def_node.offset - src_offset
26
+ qualified_name = "#{parameter_memo.qualifier}#{parameter_node.name}"
27
+ generation.memo_pad.flags[:rbs_annotated] = true
28
+ generation[src_offset, 0] = "#{" " * indent}# @rbs #{qualified_name}: #{type}\n"
29
+ end
30
+ true
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ 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 RbsInline
9
+ # The mission for parameter types
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.offsets[def_node.location.start_line - 1]
20
+ indent = offset - src_offset
21
+ generation.memo_pad.flags[:rbs_annotated] = true
22
+ generation[src_offset, 0] = "#{" " * indent}# @rbs return: #{method_memo.type}\n"
23
+ end
24
+ true
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ 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
+ # namespace for type with rbs-line feature
9
+ class RbsInline < Feature
10
+ # @rbs return: Array[Mission]
11
+ def create_missions
12
+ [
13
+ TypeInstanceVariableMission.new,
14
+ TypeAttrMission.new,
15
+ TypeOverloadMission.new,
16
+ TypeParameterMission.new,
17
+ TypeReturnMission.new,
18
+ # This mission must be the last
19
+ AddMagicCommentMission.new,
20
+ ]
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ require_relative "rbs_inline/add_magic_comment_mission"
28
+ require_relative "rbs_inline/type_attr_mission"
29
+ require_relative "rbs_inline/type_instance_variable_mission"
30
+ require_relative "rbs_inline/type_overload_mission"
31
+ require_relative "rbs_inline/type_parameter_mission"
32
+ require_relative "rbs_inline/type_return_mission"
@@ -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
+ # the class to correct `def foo: Some ...` -> `def foo ...`
9
+ class ReturnValueColonCorrector < 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 return: void
18
+ def correct(parse_error, generation)
19
+ return if parse_error.location.slice != ":"
20
+
21
+ def_node = generation.root_node.statements_node_at(parse_error.location.start_offset)&.parent
22
+ return unless def_node.is_a?(Node::DefNode)
23
+
24
+ lparen_loc = def_node.lparen_loc
25
+ rparen_loc = def_node.rparen_loc
26
+ if !lparen_loc && !rparen_loc
27
+ src_offset = def_node.name_loc.end_offset
28
+ elsif lparen_loc && rparen_loc && lparen_loc.slice == "(" && rparen_loc.slice == ")"
29
+ src_offset = rparen_loc.end_offset
30
+ else
31
+ return
32
+ end
33
+ return if generation[src_offset...parse_error.location.start_offset] !~ /\A\s*\z/
34
+
35
+ right_node = generation.root_node.node_at(parse_error.location.end_offset + 1)
36
+ return_type_location = right_node&.location || return_type_location
37
+ generation[src_offset, return_type_location.end_offset - src_offset] = ""
38
+ generation.memo_pad.method_memo(def_node).type = return_type_location.slice
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module RubyModKit
6
+ class Feature
7
+ class Type
8
+ # The mission for parameter attributes
9
+ class TypeAttrMission < Mission
10
+ # @rbs @modified: bool
11
+
12
+ # @rbs return: void
13
+ def initialize
14
+ super
15
+ @modified = false
16
+ end
17
+
18
+ # @rbs generation: Generation
19
+ # @rbs return: bool
20
+ def perform(generation)
21
+ return true if @modified
22
+
23
+ generation.memo_pad.def_parents_memo.each_value do |def_parent_memo|
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
+
29
+ ivars_memo.keep_if { |_, ivar_memo| ivar_memo.attr_kind }
30
+ next if ivars_memo.empty?
31
+
32
+ add_first_separator_line = false
33
+ if attr_adding_line == 0
34
+ 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 != ""
41
+ end
42
+ line = generation.line(attr_adding_line) || next
43
+ add_separator_line = line != "\n" && line !~ /\A\s*end$/
44
+ offset = generation.src_offset(attr_adding_line) || next
45
+
46
+ body_node = def_parent_node.body_node
47
+ if body_node
48
+ first_line = generation.line(body_node)
49
+ indent = first_line[/\A\s*/] || raise(RubyModKit::Error)
50
+ else
51
+ def_parent_line = generation.line(def_parent_node)
52
+ indent = " #{def_parent_line[/\A\s*/]}"
53
+ end
54
+
55
+ generation[offset, 0] = "\n" if add_first_separator_line
56
+ ivars_memo.each do |name, ivar_memo|
57
+ attr = ivar_memo.attr_kind
58
+ attr = "#{ivar_memo.visibility} #{attr}" if ivar_memo.visibility
59
+ generation[offset, 0] = "#{indent}#{attr} :#{name}\n"
60
+ end
61
+ @modified = true
62
+ generation[offset, 0] = "\n" if add_separator_line
63
+ end
64
+ !@modified
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module RubyModKit
6
+ class Feature
7
+ # namespace for type feature
8
+ class Type < Feature
9
+ # @rbs return: Array[Corrector]
10
+ def create_correctors
11
+ [
12
+ InstanceVariableColonCorrector.new,
13
+ ParameterArrowCorrector.new,
14
+ ReturnValueColonCorrector.new,
15
+ ]
16
+ end
17
+
18
+ # @rbs return: Array[Mission]
19
+ def create_missions
20
+ [
21
+ TypeAttrMission.new,
22
+ ]
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ require_relative "type/instance_variable_colon_corrector"
29
+ require_relative "type/parameter_arrow_corrector"
30
+ require_relative "type/return_value_colon_corrector"
31
+ require_relative "type/type_attr_mission"
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module RubyModKit
6
+ # the base class of feature
7
+ class Feature
8
+ # @rbs return: Array[Corrector]
9
+ def create_correctors
10
+ []
11
+ end
12
+
13
+ # @rbs return: Array[Mission]
14
+ def create_missions
15
+ []
16
+ end
17
+ end
18
+ end
@@ -5,33 +5,53 @@
5
5
  module RubyModKit
6
6
  # The class of transpiler generation.
7
7
  class Generation
8
- # @rbs @parse_result: Prism::ParseResult
9
8
  # @rbs @script: String
10
9
  # @rbs @missions: Array[Mission]
11
- # @rbs @memo: Memo
10
+ # @rbs @memo_pad: MemoPad
12
11
  # @rbs @root_node: Node::ProgramNode
13
12
  # @rbs @offset_diff: OffsetDiff
14
13
  # @rbs @generation_num: Integer
15
14
  # @rbs @filename: String | nil
15
+ # @rbs @corrector_manager: CorrectorManager
16
+ # @rbs @features: Array[Feature]
17
+ # @rbs @config: Config
18
+ # @rbs @errors: Array[Prism::ParseError]
19
+ # @rbs @lines: Array[String]
20
+ # @rbs @offsets: Array[Integer]
16
21
 
17
- attr_reader :parse_result #: Prism::ParseResult
18
22
  attr_reader :script #: String
23
+ attr_reader :memo_pad #: MemoPad
24
+ attr_reader :root_node #: Node::ProgramNode
25
+ attr_reader :errors #: Array[Prism::ParseError]
26
+ attr_reader :lines #: Array[String]
27
+ attr_reader :offsets #: Array[Integer]
19
28
 
20
29
  # @rbs script: String
21
30
  # @rbs missions: Array[Mission]
22
- # @rbs memo: Memo
31
+ # @rbs memo_pad: MemoPad | nil
23
32
  # @rbs generation_num: Integer
33
+ # @rbs config: Config | nil
24
34
  # @rbs filename: String | nil
35
+ # @rbs corrector_manager: CorrectorManager | nil
36
+ # @rbs features: Array[Feature] | nil
25
37
  # @rbs return: void
26
- def initialize(script, missions: [], memo: Memo.new, generation_num: 0, filename: nil)
38
+ def initialize(script, missions: [], memo_pad: nil, generation_num: 0, config: nil,
39
+ filename: nil, corrector_manager: nil, features: nil)
27
40
  @script = script
28
41
  @missions = missions
29
- @memo = memo
30
42
  @generation_num = generation_num
31
43
  @filename = filename
44
+ @config = config || Config.new
45
+ @features = features || @config.features
46
+
47
+ @memo_pad = memo_pad || MemoPad.new
48
+ @corrector_manager = corrector_manager || CorrectorManager.new(@features)
32
49
  @offset_diff = OffsetDiff.new
33
- @parse_result = Prism.parse(@script)
34
- @root_node = Node::ProgramNode.new(@parse_result.value)
50
+ parse_result = Prism.parse(@script)
51
+ @errors = parse_result.errors
52
+ @lines = parse_result.source.lines
53
+ @offsets = parse_result.source.offsets
54
+ @root_node = Node::ProgramNode.new(parse_result.value)
35
55
  init_missions
36
56
  end
37
57
 
@@ -39,11 +59,11 @@ module RubyModKit
39
59
  def init_missions
40
60
  return unless first_generation?
41
61
 
42
- add_mission(Mission::FixParseError.new)
43
- add_mission(Mission::TypeAttr.new)
44
- add_mission(Mission::Overload.new)
45
- add_mission(Mission::TypeParameter.new)
46
- add_mission(Mission::TypeReturn.new)
62
+ @features.each do |feature|
63
+ feature.create_missions.each do |mission|
64
+ add_mission(mission)
65
+ end
66
+ end
47
67
  end
48
68
 
49
69
  # @rbs return: bool
@@ -53,16 +73,25 @@ module RubyModKit
53
73
 
54
74
  # @rbs return: Generation
55
75
  def succ
76
+ if @errors.empty?
77
+ perform_missions
78
+ else
79
+ perform_corrector
80
+ end
56
81
  @missions.each do |mission|
57
82
  mission.succ(@offset_diff)
58
83
  end
59
- @memo.succ(@offset_diff)
84
+ @memo_pad.succ(@offset_diff)
85
+
60
86
  Generation.new(
61
87
  @script,
62
88
  missions: @missions,
63
- memo: @memo,
89
+ memo_pad: @memo_pad,
64
90
  generation_num: @generation_num + 1,
65
91
  filename: @filename,
92
+ corrector_manager: @corrector_manager,
93
+ features: @features,
94
+ config: @config,
66
95
  )
67
96
  end
68
97
 
@@ -71,14 +100,9 @@ module RubyModKit
71
100
  "#{@filename || "(eval)"}[gen #{@generation_num}]"
72
101
  end
73
102
 
74
- # @rbs return: void
75
- def resolve
76
- perform_missions
77
- end
78
-
79
103
  # @rbs return: bool
80
104
  def completed?
81
- @parse_result.errors.empty? && @missions.empty?
105
+ @errors.empty? && @missions.empty?
82
106
  end
83
107
 
84
108
  # @rbs src_offset: Integer
@@ -98,14 +122,21 @@ module RubyModKit
98
122
  @script[dst_range] || raise(RubyModKit::Error, "Invalid range")
99
123
  end
100
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)
130
+ end
131
+
101
132
  # @rbs (Integer) -> String
102
- # | (Node) -> String
133
+ # | (Node::BaseNode) -> String
103
134
  # | (Prism::ParseError) -> String
104
135
  def line(*args)
105
136
  case args
106
137
  in [Integer]
107
138
  line__overload0(*args)
108
- in [Node]
139
+ in [Node::BaseNode]
109
140
  line__overload1(*args)
110
141
  in [Prism::ParseError]
111
142
  line__overload2(*args)
@@ -115,14 +146,13 @@ module RubyModKit
115
146
  # @rbs line_num: Integer
116
147
  # @rbs return: String
117
148
  def line__overload0(line_num)
118
- offset = @offset_diff[@parse_result.source.offsets[line_num]]
119
- (@script.match(/.*\n?/, offset) && Regexp.last_match(0)) || raise(RubyModKit::Error)
149
+ line_by_offset(@offsets[line_num])
120
150
  end
121
151
 
122
- # @rbs node: Node
152
+ # @rbs node: Node::BaseNode
123
153
  # @rbs return: String
124
154
  def line__overload1(node)
125
- line(node.prism_node.location.start_line - 1)
155
+ line(node.location.start_line - 1)
126
156
  end
127
157
 
128
158
  # @rbs parse_error: Prism::ParseError
@@ -145,7 +175,7 @@ module RubyModKit
145
175
  # @rbs line_num: Integer
146
176
  # @rbs return: Integer | nil
147
177
  def src_offset__overload0(line_num)
148
- parse_result.source.offsets[line_num]
178
+ @offsets[line_num]
149
179
  end
150
180
 
151
181
  # @rbs parse_error: Prism::ParseError
@@ -154,10 +184,15 @@ module RubyModKit
154
184
  src_offset(parse_error.location.start_line - 1)
155
185
  end
156
186
 
187
+ # @rbs return: void
188
+ def perform_corrector
189
+ @corrector_manager.perform(self)
190
+ end
191
+
157
192
  # @rbs return: void
158
193
  def perform_missions
159
194
  @missions.delete_if do |mission|
160
- mission.perform(self, @root_node, @parse_result, @memo) || break
195
+ mission.perform(self) || break
161
196
  end
162
197
  end
163
198
 
@@ -166,5 +201,17 @@ module RubyModKit
166
201
  def add_mission(mission)
167
202
  @missions << mission
168
203
  end
204
+
205
+ class << self
206
+ # @rbs src: String
207
+ # @rbs filename: String | nil
208
+ # @rbs config: Config | nil
209
+ # @rbs return: Generation
210
+ def resolve(src, filename: nil, config: nil)
211
+ generation = Generation.new(src.dup, filename: filename, config: config)
212
+ generation = generation.succ until generation.completed?
213
+ generation
214
+ end
215
+ end
169
216
  end
170
217
  end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module RubyModKit
6
+ module Memo
7
+ # The memo for def parent (class, module)
8
+ class DefParentMemo < OffsetMemo
9
+ # @rbs @ivars_memo: Hash[Symbol, Memo::IvarMemo]
10
+
11
+ attr_reader :ivars_memo #: Hash[Symbol, Memo::IvarMemo]
12
+
13
+ # @rbs def_parent_node: Node::DefParentNode
14
+ # @rbs return: void
15
+ def initialize(def_parent_node)
16
+ @ivars_memo = {}
17
+ super(def_parent_node.offset)
18
+ end
19
+
20
+ # @rbs name: Symbol
21
+ # @rbs return: Memo::IvarMemo
22
+ def ivar_memo(name)
23
+ @ivars_memo[name] ||= Memo::IvarMemo.new(name)
24
+ end
25
+
26
+ # @rbs offset_diff: OffsetDiff
27
+ # @rbs return: void
28
+ def succ(offset_diff)
29
+ @ivars_memo.each_value do |ivar_memo|
30
+ ivar_memo.succ(offset_diff)
31
+ end
32
+ super
33
+ end
34
+ end
35
+ end
36
+ end
@@ -3,26 +3,33 @@
3
3
  # rbs_inline: enabled
4
4
 
5
5
  module RubyModKit
6
- class Memo
6
+ module Memo
7
7
  # The memo for parameter type
8
- class Ivar
8
+ class IvarMemo
9
9
  # @rbs @type: nil | String
10
10
  # @rbs @attr_kind: nil | Symbol
11
+ # @rbs @offset: nil | Integer
12
+ # @rbs @indent: String
11
13
  # @rbs @name: Symbol
14
+ # @rbs @visibility: nil | Symbol
12
15
 
13
16
  attr_reader :type #: nil | String
14
17
  attr_reader :attr_kind #: nil | Symbol
18
+ attr_accessor :offset #: nil | Integer
19
+ attr_accessor :indent #: String
20
+ attr_accessor :visibility #: nil | Symbol
15
21
 
16
22
  # @rbs name: Symbol
17
23
  # @rbs return: void
18
24
  def initialize(name)
19
25
  @name = name
26
+ @indent = ""
20
27
  end
21
28
 
22
29
  # @rbs type: String
23
30
  # @rbs return: void
24
31
  def type=(type)
25
- @type = Memo.unify_type(type)
32
+ @type = RubyModKit.unify_type(type)
26
33
  end
27
34
 
28
35
  # @rbs kind: Symbol | String
@@ -37,6 +44,15 @@ module RubyModKit
37
44
  @attr_kind = :attr_accessor
38
45
  end
39
46
  end
47
+
48
+ # @rbs offset_diff: OffsetDiff
49
+ # @rbs return: void
50
+ def succ(offset_diff)
51
+ offset = @offset
52
+ return unless offset
53
+
54
+ @offset = offset_diff[offset]
55
+ end
40
56
  end
41
57
  end
42
58
  end