ruby_mod_kit 0.0.2 → 0.0.4

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