ruby_mod_kit 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +14 -8
  3. data/lib/ruby_mod_kit/cli.rb +10 -1
  4. data/lib/ruby_mod_kit/core_ext/eval.rb +36 -0
  5. data/lib/ruby_mod_kit/core_ext/load.rb +74 -0
  6. data/lib/ruby_mod_kit/core_ext.rb +7 -0
  7. data/lib/ruby_mod_kit/corrector.rb +22 -0
  8. data/lib/ruby_mod_kit/corrector_manager.rb +68 -0
  9. data/lib/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_corrector.rb +42 -0
  10. data/lib/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_mission.rb +49 -0
  11. data/lib/ruby_mod_kit/feature/instance_variable_parameter.rb +27 -0
  12. data/lib/ruby_mod_kit/feature/overload/overload_mission.rb +80 -0
  13. data/lib/ruby_mod_kit/feature/overload.rb +19 -0
  14. data/lib/ruby_mod_kit/feature/type/instance_variable_colon_corrector.rb +49 -0
  15. data/lib/ruby_mod_kit/feature/type/parameter_arrow_corrector.rb +90 -0
  16. data/lib/ruby_mod_kit/feature/type/rbs_inline/type_attr_mission.rb +41 -0
  17. data/lib/ruby_mod_kit/feature/type/rbs_inline/type_instance_variable_mission.rb +31 -0
  18. data/lib/ruby_mod_kit/feature/type/rbs_inline/type_overload_mission.rb +43 -0
  19. data/lib/ruby_mod_kit/feature/type/rbs_inline/type_parameter_mission.rb +38 -0
  20. data/lib/ruby_mod_kit/feature/type/rbs_inline/type_return_mission.rb +32 -0
  21. data/lib/ruby_mod_kit/feature/type/rbs_inline.rb +29 -0
  22. data/lib/ruby_mod_kit/feature/type/return_value_colon_corrector.rb +45 -0
  23. data/lib/ruby_mod_kit/feature/type/type_attr_mission.rb +67 -0
  24. data/lib/ruby_mod_kit/feature/type.rb +31 -0
  25. data/lib/ruby_mod_kit/feature.rb +24 -0
  26. data/lib/ruby_mod_kit/generation.rb +60 -22
  27. data/lib/ruby_mod_kit/memo/def_parent_memo.rb +36 -0
  28. data/lib/ruby_mod_kit/memo/{ivar.rb → ivar_memo.rb} +17 -3
  29. data/lib/ruby_mod_kit/memo/{method.rb → method_memo.rb} +7 -7
  30. data/lib/ruby_mod_kit/memo/offset_memo.rb +1 -1
  31. data/lib/ruby_mod_kit/memo/overload_memo.rb +46 -0
  32. data/lib/ruby_mod_kit/memo/{parameter.rb → parameter_memo.rb} +3 -3
  33. data/lib/ruby_mod_kit/memo.rb +7 -64
  34. data/lib/ruby_mod_kit/memo_pad.rb +69 -0
  35. data/lib/ruby_mod_kit/mission.rb +5 -24
  36. data/lib/ruby_mod_kit/node/base_node.rb +137 -0
  37. data/lib/ruby_mod_kit/node/call_node.rb +10 -6
  38. data/lib/ruby_mod_kit/node/def_node.rb +10 -6
  39. data/lib/ruby_mod_kit/node/def_parent_node.rb +41 -0
  40. data/lib/ruby_mod_kit/node/parameter_node.rb +12 -8
  41. data/lib/ruby_mod_kit/node/program_node.rb +2 -2
  42. data/lib/ruby_mod_kit/node/statements_node.rb +10 -6
  43. data/lib/ruby_mod_kit/node/symbol_node.rb +10 -6
  44. data/lib/ruby_mod_kit/node/untyped_node.rb +10 -6
  45. data/lib/ruby_mod_kit/node/wrap.rb +43 -0
  46. data/lib/ruby_mod_kit/node.rb +5 -149
  47. data/lib/ruby_mod_kit/offset_diff.rb +12 -6
  48. data/lib/ruby_mod_kit/version.rb +1 -1
  49. data/lib/ruby_mod_kit.rb +43 -11
  50. data/ruby_mod_kit.gemspec +1 -6
  51. data/sig/generated/ruby_mod_kit/core_ext/eval.rbs +17 -0
  52. data/sig/generated/ruby_mod_kit/core_ext/load.rbs +33 -0
  53. data/sig/generated/ruby_mod_kit/corrector.rbs +16 -0
  54. data/sig/generated/ruby_mod_kit/corrector_manager.rbs +26 -0
  55. data/sig/generated/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_corrector.rbs +20 -0
  56. data/sig/generated/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_mission.rbs +21 -0
  57. data/sig/generated/ruby_mod_kit/feature/instance_variable_parameter.rbs +14 -0
  58. data/sig/generated/ruby_mod_kit/feature/overload/overload_mission.rbs +24 -0
  59. data/sig/generated/ruby_mod_kit/feature/overload.rbs +11 -0
  60. data/sig/generated/ruby_mod_kit/feature/type/instance_variable_colon_corrector.rbs +20 -0
  61. data/sig/generated/ruby_mod_kit/feature/type/parameter_arrow_corrector.rbs +39 -0
  62. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_attr_mission.rbs +19 -0
  63. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_instance_variable_mission.rbs +19 -0
  64. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_overload_mission.rbs +19 -0
  65. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_parameter_mission.rbs +19 -0
  66. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_return_mission.rbs +19 -0
  67. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline.rbs +13 -0
  68. data/sig/generated/ruby_mod_kit/feature/type/return_value_colon_corrector.rbs +20 -0
  69. data/sig/generated/ruby_mod_kit/feature/type/type_attr_mission.rbs +20 -0
  70. data/sig/generated/ruby_mod_kit/feature/type.rbs +14 -0
  71. data/sig/generated/ruby_mod_kit/feature.rbs +16 -0
  72. data/sig/generated/ruby_mod_kit/generation.rbs +25 -10
  73. data/sig/generated/ruby_mod_kit/memo/def_parent_memo.rbs +24 -0
  74. data/sig/generated/ruby_mod_kit/memo/{ivar.rbs → ivar_memo.rbs} +15 -3
  75. data/sig/generated/ruby_mod_kit/memo/{method.rbs → method_memo.rbs} +8 -8
  76. data/sig/generated/ruby_mod_kit/memo/offset_memo.rbs +1 -1
  77. data/sig/generated/ruby_mod_kit/memo/overload_memo.rbs +32 -0
  78. data/sig/generated/ruby_mod_kit/memo/{parameter.rbs → parameter_memo.rbs} +3 -3
  79. data/sig/generated/ruby_mod_kit/memo.rbs +2 -36
  80. data/sig/generated/ruby_mod_kit/memo_pad.rbs +46 -0
  81. data/sig/generated/ruby_mod_kit/mission.rbs +4 -12
  82. data/sig/generated/ruby_mod_kit/node/base_node.rbs +65 -0
  83. data/sig/generated/ruby_mod_kit/node/call_node.rbs +11 -6
  84. data/sig/generated/ruby_mod_kit/node/def_node.rbs +11 -6
  85. data/sig/generated/ruby_mod_kit/node/def_parent_node.rbs +31 -0
  86. data/sig/generated/ruby_mod_kit/node/parameter_node.rbs +13 -8
  87. data/sig/generated/ruby_mod_kit/node/program_node.rbs +2 -2
  88. data/sig/generated/ruby_mod_kit/node/statements_node.rbs +11 -6
  89. data/sig/generated/ruby_mod_kit/node/symbol_node.rbs +11 -6
  90. data/sig/generated/ruby_mod_kit/node/untyped_node.rbs +11 -6
  91. data/sig/generated/ruby_mod_kit/node/wrap.rbs +12 -0
  92. data/sig/generated/ruby_mod_kit/node.rbs +2 -58
  93. data/sig/generated/ruby_mod_kit/offset_diff.rbs +3 -1
  94. data/sig/generated/ruby_mod_kit.rbs +13 -2
  95. data/sig/thor.rbs +2 -0
  96. metadata +63 -43
  97. data/lib/ruby_mod_kit/memo/class.rb +0 -27
  98. data/lib/ruby_mod_kit/mission/fix_parse_error.rb +0 -213
  99. data/lib/ruby_mod_kit/mission/ivar_arg.rb +0 -42
  100. data/lib/ruby_mod_kit/mission/overload.rb +0 -73
  101. data/lib/ruby_mod_kit/mission/type_attr.rb +0 -75
  102. data/lib/ruby_mod_kit/mission/type_parameter.rb +0 -39
  103. data/lib/ruby_mod_kit/mission/type_return.rb +0 -33
  104. data/lib/ruby_mod_kit/node/class_node.rb +0 -37
  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/class.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/mission/fix_parse_error.rbs +0 -73
  111. data/sig/generated/ruby_mod_kit/mission/ivar_arg.rbs +0 -19
  112. data/sig/generated/ruby_mod_kit/mission/overload.rbs +0 -20
  113. data/sig/generated/ruby_mod_kit/mission/type_attr.rbs +0 -18
  114. data/sig/generated/ruby_mod_kit/mission/type_parameter.rbs +0 -18
  115. data/sig/generated/ruby_mod_kit/mission/type_return.rbs +0 -18
  116. data/sig/generated/ruby_mod_kit/node/class_node.rbs +0 -29
  117. data/sig/generated/ruby_mod_kit/transpiler.rbs +0 -11
@@ -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
@@ -0,0 +1,38 @@
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 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.parameters_memo.each do |offset, parameter_memo|
18
+ next if parameter_memo.untyped?
19
+
20
+ def_node = root_node.def_node_at(offset)
21
+ raise RubyModKit::Error, "DefNode not found" if !def_node || !def_node.is_a?(Node::DefNode)
22
+
23
+ parameter_node = root_node.parameter_node_at(offset)
24
+ raise RubyModKit::Error, "ParameterNode not found" unless parameter_node
25
+
26
+ type = parameter_memo.type
27
+ src_offset = parse_result.source.offsets[def_node.location.start_line - 1]
28
+ indent = def_node.offset - src_offset
29
+ qualified_name = "#{parameter_memo.qualifier}#{parameter_node.name}"
30
+ generation[src_offset, 0] = "#{" " * indent}# @rbs #{qualified_name}: #{type}\n"
31
+ end
32
+ true
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ 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
+ class RbsInline
9
+ # The mission for parameter types
10
+ class TypeReturnMission < 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.methods_memo.each do |offset, method_memo|
18
+ def_node = root_node.def_node_at(offset)
19
+ raise RubyModKit::Error, "DefNode not found" if !def_node || !def_node.is_a?(Node::DefNode)
20
+ next if method_memo.untyped?
21
+
22
+ src_offset = parse_result.source.offsets[def_node.location.start_line - 1]
23
+ indent = offset - src_offset
24
+ generation[src_offset, 0] = "#{" " * indent}# @rbs return: #{method_memo.type}\n"
25
+ end
26
+ true
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ 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
+ # 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
+ ]
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ require_relative "rbs_inline/type_attr_mission"
26
+ require_relative "rbs_inline/type_instance_variable_mission"
27
+ require_relative "rbs_inline/type_overload_mission"
28
+ require_relative "rbs_inline/type_parameter_mission"
29
+ require_relative "rbs_inline/type_return_mission"
@@ -0,0 +1,45 @@
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 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_node = root_node.statements_node_at(parse_error.location.start_offset)&.parent
24
+ return unless def_node.is_a?(Node::DefNode)
25
+
26
+ lparen_loc = def_node.lparen_loc
27
+ rparen_loc = def_node.rparen_loc
28
+ if !lparen_loc && !rparen_loc
29
+ src_offset = def_node.name_loc.end_offset
30
+ elsif lparen_loc && rparen_loc && lparen_loc.slice == "(" && rparen_loc.slice == ")"
31
+ src_offset = rparen_loc.end_offset
32
+ else
33
+ return
34
+ end
35
+ return if generation[src_offset...parse_error.location.start_offset] !~ /\A\s*\z/
36
+
37
+ right_node = root_node.node_at(parse_error.location.end_offset + 1)
38
+ return_type_location = right_node&.location || return_type_location
39
+ generation[src_offset, return_type_location.end_offset - src_offset] = ""
40
+ memo_pad.method_memo(def_node).type = return_type_location.slice
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,67 @@
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 return: void
11
+ def initialize
12
+ super
13
+ @modified = false
14
+ end
15
+
16
+ # @rbs generation: Generation
17
+ # @rbs root_node: Node::ProgramNode
18
+ # @rbs _parse_result: Prism::ParseResult
19
+ # @rbs memo_pad: MemoPad
20
+ # @rbs return: bool
21
+ def perform(generation, root_node, _parse_result, memo_pad)
22
+ return true if @modified
23
+
24
+ memo_pad.def_parents_memo.each_value do |def_parent_memo|
25
+ ivars_memo = def_parent_memo.ivars_memo.dup
26
+ def_parent_node = root_node.def_parent_node_at(def_parent_memo.offset) || raise(RubyModKit::Error)
27
+ attr_adding_line = 0
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
+ generation[offset, 0] = "#{indent}#{ivar_memo.attr_kind} :#{name}\n"
58
+ end
59
+ @modified = true
60
+ generation[offset, 0] = "\n" if add_separator_line
61
+ end
62
+ !@modified
63
+ end
64
+ end
65
+ end
66
+ end
67
+ 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,24 @@
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 other: Feature
9
+ # @rbs return: -1 | 0 | 1 | nil
10
+ def <=>(other)
11
+ self.class.name <=> other.class.name
12
+ end
13
+
14
+ # @rbs return: Array[Corrector]
15
+ def create_correctors
16
+ []
17
+ end
18
+
19
+ # @rbs return: Array[Mission]
20
+ def create_missions
21
+ []
22
+ end
23
+ end
24
+ end
@@ -8,27 +8,40 @@ module RubyModKit
8
8
  # @rbs @parse_result: Prism::ParseResult
9
9
  # @rbs @script: String
10
10
  # @rbs @missions: Array[Mission]
11
- # @rbs @memo: Memo
11
+ # @rbs @memo_pad: MemoPad
12
12
  # @rbs @root_node: Node::ProgramNode
13
13
  # @rbs @offset_diff: OffsetDiff
14
14
  # @rbs @generation_num: Integer
15
15
  # @rbs @filename: String | nil
16
+ # @rbs @corrector_manager: CorrectorManager
17
+ # @rbs @features: Array[Feature]
16
18
 
17
19
  attr_reader :parse_result #: Prism::ParseResult
18
20
  attr_reader :script #: String
19
21
 
20
22
  # @rbs script: String
21
23
  # @rbs missions: Array[Mission]
22
- # @rbs memo: Memo
24
+ # @rbs memo_pad: MemoPad | nil
23
25
  # @rbs generation_num: Integer
24
26
  # @rbs filename: String | nil
27
+ # @rbs corrector_manager: CorrectorManager | nil
28
+ # @rbs features: Array[Feature] | nil
25
29
  # @rbs return: void
26
- def initialize(script, missions: [], memo: Memo.new, generation_num: 0, filename: nil)
30
+ def initialize(script, missions: [], memo_pad: nil, generation_num: 0,
31
+ filename: nil, corrector_manager: nil, features: nil)
27
32
  @script = script
28
33
  @missions = missions
29
- @memo = memo
30
34
  @generation_num = generation_num
31
35
  @filename = filename
36
+ @features = features || [
37
+ Feature::InstanceVariableParameter.new,
38
+ Feature::Overload.new,
39
+ Feature::Type.new,
40
+ Feature::Type::RbsInline.new,
41
+ ].sort
42
+
43
+ @memo_pad = memo_pad || MemoPad.new
44
+ @corrector_manager = corrector_manager || CorrectorManager.new(@features)
32
45
  @offset_diff = OffsetDiff.new
33
46
  @parse_result = Prism.parse(@script)
34
47
  @root_node = Node::ProgramNode.new(@parse_result.value)
@@ -39,11 +52,11 @@ module RubyModKit
39
52
  def init_missions
40
53
  return unless first_generation?
41
54
 
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)
55
+ @features.each do |feature|
56
+ feature.create_missions.each do |mission|
57
+ add_mission(mission)
58
+ end
59
+ end
47
60
  end
48
61
 
49
62
  # @rbs return: bool
@@ -53,16 +66,24 @@ module RubyModKit
53
66
 
54
67
  # @rbs return: Generation
55
68
  def succ
69
+ if @parse_result.errors.empty?
70
+ perform_missions
71
+ else
72
+ perform_corrector
73
+ end
56
74
  @missions.each do |mission|
57
75
  mission.succ(@offset_diff)
58
76
  end
59
- @memo.succ(@offset_diff)
77
+ @memo_pad.succ(@offset_diff)
78
+
60
79
  Generation.new(
61
80
  @script,
62
81
  missions: @missions,
63
- memo: @memo,
82
+ memo_pad: @memo_pad,
64
83
  generation_num: @generation_num + 1,
65
84
  filename: @filename,
85
+ corrector_manager: @corrector_manager,
86
+ features: @features,
66
87
  )
67
88
  end
68
89
 
@@ -71,11 +92,6 @@ module RubyModKit
71
92
  "#{@filename || "(eval)"}[gen #{@generation_num}]"
72
93
  end
73
94
 
74
- # @rbs return: void
75
- def resolve
76
- perform_missions
77
- end
78
-
79
95
  # @rbs return: bool
80
96
  def completed?
81
97
  @parse_result.errors.empty? && @missions.empty?
@@ -98,14 +114,21 @@ module RubyModKit
98
114
  @script[dst_range] || raise(RubyModKit::Error, "Invalid range")
99
115
  end
100
116
 
117
+ # @rbs offset: Integer
118
+ # @rbs return: String
119
+ def line_by_offset(offset)
120
+ offset = @offset_diff[offset]
121
+ (@script.match(/.*\n?/, offset) && Regexp.last_match(0)) || raise(RubyModKit::Error)
122
+ end
123
+
101
124
  # @rbs (Integer) -> String
102
- # | (Node) -> String
125
+ # | (Node::BaseNode) -> String
103
126
  # | (Prism::ParseError) -> String
104
127
  def line(*args)
105
128
  case args
106
129
  in [Integer]
107
130
  line__overload0(*args)
108
- in [Node]
131
+ in [Node::BaseNode]
109
132
  line__overload1(*args)
110
133
  in [Prism::ParseError]
111
134
  line__overload2(*args)
@@ -115,11 +138,10 @@ module RubyModKit
115
138
  # @rbs line_num: Integer
116
139
  # @rbs return: String
117
140
  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)
141
+ line_by_offset(@parse_result.source.offsets[line_num])
120
142
  end
121
143
 
122
- # @rbs node: Node
144
+ # @rbs node: Node::BaseNode
123
145
  # @rbs return: String
124
146
  def line__overload1(node)
125
147
  line(node.prism_node.location.start_line - 1)
@@ -154,10 +176,15 @@ module RubyModKit
154
176
  src_offset(parse_error.location.start_line - 1)
155
177
  end
156
178
 
179
+ # @rbs return: void
180
+ def perform_corrector
181
+ @corrector_manager.perform(self, @root_node, @parse_result, @memo_pad)
182
+ end
183
+
157
184
  # @rbs return: void
158
185
  def perform_missions
159
186
  @missions.delete_if do |mission|
160
- mission.perform(self, @root_node, @parse_result, @memo) || break
187
+ mission.perform(self, @root_node, @parse_result, @memo_pad) || break
161
188
  end
162
189
  end
163
190
 
@@ -166,5 +193,16 @@ module RubyModKit
166
193
  def add_mission(mission)
167
194
  @missions << mission
168
195
  end
196
+
197
+ class << self
198
+ # @rbs src: String
199
+ # @rbs filename: String | nil
200
+ # @rbs return: Generation
201
+ def resolve(src, filename: nil)
202
+ generation = Generation.new(src.dup, filename: filename)
203
+ generation = generation.succ until generation.completed?
204
+ generation
205
+ end
206
+ end
169
207
  end
170
208
  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,31 @@
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
12
14
 
13
15
  attr_reader :type #: nil | String
14
16
  attr_reader :attr_kind #: nil | Symbol
17
+ attr_accessor :offset #: nil | Integer
18
+ attr_accessor :indent #: String
15
19
 
16
20
  # @rbs name: Symbol
17
21
  # @rbs return: void
18
22
  def initialize(name)
19
23
  @name = name
24
+ @indent = ""
20
25
  end
21
26
 
22
27
  # @rbs type: String
23
28
  # @rbs return: void
24
29
  def type=(type)
25
- @type = Memo.unify_type(type)
30
+ @type = RubyModKit.unify_type(type)
26
31
  end
27
32
 
28
33
  # @rbs kind: Symbol | String
@@ -37,6 +42,15 @@ module RubyModKit
37
42
  @attr_kind = :attr_accessor
38
43
  end
39
44
  end
45
+
46
+ # @rbs offset_diff: OffsetDiff
47
+ # @rbs return: void
48
+ def succ(offset_diff)
49
+ offset = @offset
50
+ return unless offset
51
+
52
+ @offset = offset_diff[offset]
53
+ end
40
54
  end
41
55
  end
42
56
  end
@@ -3,15 +3,15 @@
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 Method < OffsetMemo
8
+ class MethodMemo < OffsetMemo
9
9
  # @rbs @name: Symbol
10
- # @rbs @parameters: Set[Memo::Parameter]
10
+ # @rbs @parameters: Set[Memo::ParameterMemo]
11
11
  # @rbs @type: String
12
12
 
13
13
  attr_reader :name #: Symbol
14
- attr_reader :parameters #: Set[Memo::Parameter]
14
+ attr_reader :parameters #: Set[Memo::ParameterMemo]
15
15
  attr_reader :type #: String
16
16
 
17
17
  UNTYPED = "untyped"
@@ -27,8 +27,8 @@ module RubyModKit
27
27
  super(node.offset)
28
28
  end
29
29
 
30
- # @rbs parameter_memo: Memo::Parameter
31
- # @rbs return: Memo::Parameter
30
+ # @rbs parameter_memo: Memo::ParameterMemo
31
+ # @rbs return: Memo::ParameterMemo
32
32
  def add_parameter(parameter_memo)
33
33
  @parameters << parameter_memo
34
34
  parameter_memo
@@ -42,7 +42,7 @@ module RubyModKit
42
42
  # @rbs type: String
43
43
  # @rbs return: void
44
44
  def type=(type)
45
- @type = Memo.unify_type(type)
45
+ @type = RubyModKit.unify_type(type)
46
46
  end
47
47
  end
48
48
  end
@@ -3,7 +3,7 @@
3
3
  # rbs_inline: enabled
4
4
 
5
5
  module RubyModKit
6
- class Memo
6
+ module Memo
7
7
  # The base class for located memo
8
8
  class OffsetMemo
9
9
  # @rbs @offset: Integer