ruby_mod_kit 0.0.4 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby_mod_kit.yml +1 -0
  3. data/.yardopts +3 -0
  4. data/README.md +89 -0
  5. data/examples/user.rb +4 -16
  6. data/lib/ruby_mod_kit/cli.rb +5 -0
  7. data/lib/ruby_mod_kit/config.rb +6 -1
  8. data/lib/ruby_mod_kit/core_ext/eval.rb +13 -10
  9. data/lib/ruby_mod_kit/core_ext/load.rb +10 -0
  10. data/lib/ruby_mod_kit/corrector.rb +8 -0
  11. data/lib/ruby_mod_kit/corrector_manager.rb +16 -6
  12. data/lib/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_corrector.rb +4 -0
  13. data/lib/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_mission.rb +3 -1
  14. data/lib/ruby_mod_kit/feature/instance_variable_parameter.rb +2 -0
  15. data/lib/ruby_mod_kit/feature/overload/overload_mission.rb +44 -13
  16. data/lib/ruby_mod_kit/feature/overload.rb +1 -0
  17. data/lib/ruby_mod_kit/feature/type/check/arguments/add_arguments_checker_mission.rb +58 -0
  18. data/lib/ruby_mod_kit/feature/type/check/arguments.rb +25 -0
  19. data/lib/ruby_mod_kit/feature/type/instance_variable_colon_corrector.rb +13 -4
  20. data/lib/ruby_mod_kit/feature/type/parameter_arrow_corrector.rb +41 -5
  21. data/lib/ruby_mod_kit/feature/type/rbs_inline/add_magic_comment_mission.rb +3 -0
  22. data/lib/ruby_mod_kit/feature/type/rbs_inline/type_attr_mission.rb +2 -0
  23. data/lib/ruby_mod_kit/feature/type/rbs_inline/type_instance_variable_mission.rb +5 -2
  24. data/lib/ruby_mod_kit/feature/type/rbs_inline/type_overload_mission.rb +3 -2
  25. data/lib/ruby_mod_kit/feature/type/rbs_inline/type_parameter_mission.rb +7 -4
  26. data/lib/ruby_mod_kit/feature/type/rbs_inline/type_return_mission.rb +3 -1
  27. data/lib/ruby_mod_kit/feature/type/rbs_inline.rb +1 -0
  28. data/lib/ruby_mod_kit/feature/type/return_value_colon_corrector.rb +5 -0
  29. data/lib/ruby_mod_kit/feature/type/type_attr_mission.rb +6 -9
  30. data/lib/ruby_mod_kit/feature/type/yard/type_parameter_mission.rb +37 -0
  31. data/lib/ruby_mod_kit/feature/type/yard/type_return_mission.rb +32 -0
  32. data/lib/ruby_mod_kit/feature/type/yard.rb +34 -0
  33. data/lib/ruby_mod_kit/feature/type.rb +2 -0
  34. data/lib/ruby_mod_kit/feature.rb +2 -0
  35. data/lib/ruby_mod_kit/generation.rb +67 -49
  36. data/lib/ruby_mod_kit/memo/def_parent_memo.rb +6 -0
  37. data/lib/ruby_mod_kit/memo/ivar_memo.rb +18 -8
  38. data/lib/ruby_mod_kit/memo/method_memo.rb +8 -1
  39. data/lib/ruby_mod_kit/memo/offset_memo.rb +4 -0
  40. data/lib/ruby_mod_kit/memo/overload_memo.rb +9 -1
  41. data/lib/ruby_mod_kit/memo/parameter_memo.rb +10 -3
  42. data/lib/ruby_mod_kit/memo_pad.rb +34 -0
  43. data/lib/ruby_mod_kit/mission.rb +2 -4
  44. data/lib/ruby_mod_kit/node/base_node.rb +43 -3
  45. data/lib/ruby_mod_kit/node/begin_node.rb +35 -0
  46. data/lib/ruby_mod_kit/node/call_node.rb +4 -0
  47. data/lib/ruby_mod_kit/node/def_node.rb +36 -0
  48. data/lib/ruby_mod_kit/node/def_parent_node.rb +10 -2
  49. data/lib/ruby_mod_kit/node/parameter_node.rb +7 -2
  50. data/lib/ruby_mod_kit/node/program_node.rb +3 -0
  51. data/lib/ruby_mod_kit/node/statements_node.rb +4 -0
  52. data/lib/ruby_mod_kit/node/symbol_node.rb +7 -2
  53. data/lib/ruby_mod_kit/node/untyped_node.rb +4 -0
  54. data/lib/ruby_mod_kit/node/wrap.rb +7 -1
  55. data/lib/ruby_mod_kit/node.rb +1 -0
  56. data/lib/ruby_mod_kit/offset_diff.rb +6 -0
  57. data/lib/ruby_mod_kit/version.rb +1 -1
  58. data/lib/ruby_mod_kit.rb +29 -8
  59. data/sig/generated/ruby_mod_kit/cli.rbs +5 -0
  60. data/sig/generated/ruby_mod_kit/config.rbs +7 -2
  61. data/sig/generated/ruby_mod_kit/core_ext/eval.rbs +11 -2
  62. data/sig/generated/ruby_mod_kit/core_ext/load.rbs +10 -0
  63. data/sig/generated/ruby_mod_kit/corrector.rbs +8 -0
  64. data/sig/generated/ruby_mod_kit/corrector_manager.rbs +7 -1
  65. data/sig/generated/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_corrector.rbs +4 -0
  66. data/sig/generated/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_mission.rbs +2 -0
  67. data/sig/generated/ruby_mod_kit/feature/instance_variable_parameter.rbs +2 -0
  68. data/sig/generated/ruby_mod_kit/feature/overload/overload_mission.rbs +3 -0
  69. data/sig/generated/ruby_mod_kit/feature/overload.rbs +1 -0
  70. data/sig/generated/ruby_mod_kit/feature/type/check/arguments/add_arguments_checker_mission.rbs +18 -0
  71. data/sig/generated/ruby_mod_kit/feature/type/check/arguments.rbs +17 -0
  72. data/sig/generated/ruby_mod_kit/feature/type/instance_variable_colon_corrector.rbs +4 -0
  73. data/sig/generated/ruby_mod_kit/feature/type/parameter_arrow_corrector.rbs +19 -0
  74. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/add_magic_comment_mission.rbs +3 -0
  75. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_attr_mission.rbs +2 -0
  76. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_instance_variable_mission.rbs +2 -0
  77. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_overload_mission.rbs +2 -0
  78. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_parameter_mission.rbs +2 -0
  79. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_return_mission.rbs +2 -0
  80. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline.rbs +1 -0
  81. data/sig/generated/ruby_mod_kit/feature/type/return_value_colon_corrector.rbs +4 -0
  82. data/sig/generated/ruby_mod_kit/feature/type/type_attr_mission.rbs +3 -0
  83. data/sig/generated/ruby_mod_kit/feature/type/yard/type_parameter_mission.rbs +18 -0
  84. data/sig/generated/ruby_mod_kit/feature/type/yard/type_return_mission.rbs +18 -0
  85. data/sig/generated/ruby_mod_kit/feature/type/yard.rbs +20 -0
  86. data/sig/generated/ruby_mod_kit/feature/type.rbs +2 -0
  87. data/sig/generated/ruby_mod_kit/feature.rbs +2 -0
  88. data/sig/generated/ruby_mod_kit/generation.rbs +46 -25
  89. data/sig/generated/ruby_mod_kit/memo/def_parent_memo.rbs +6 -0
  90. data/sig/generated/ruby_mod_kit/memo/ivar_memo.rbs +20 -8
  91. data/sig/generated/ruby_mod_kit/memo/method_memo.rbs +8 -1
  92. data/sig/generated/ruby_mod_kit/memo/offset_memo.rbs +4 -0
  93. data/sig/generated/ruby_mod_kit/memo/overload_memo.rbs +8 -0
  94. data/sig/generated/ruby_mod_kit/memo/parameter_memo.rbs +12 -3
  95. data/sig/generated/ruby_mod_kit/memo_pad.rbs +23 -0
  96. data/sig/generated/ruby_mod_kit/mission.rbs +2 -4
  97. data/sig/generated/ruby_mod_kit/node/base_node.rbs +36 -3
  98. data/sig/generated/ruby_mod_kit/node/begin_node.rbs +30 -0
  99. data/sig/generated/ruby_mod_kit/node/call_node.rbs +4 -0
  100. data/sig/generated/ruby_mod_kit/node/def_node.rbs +24 -0
  101. data/sig/generated/ruby_mod_kit/node/def_parent_node.rbs +11 -3
  102. data/sig/generated/ruby_mod_kit/node/parameter_node.rbs +6 -1
  103. data/sig/generated/ruby_mod_kit/node/program_node.rbs +3 -0
  104. data/sig/generated/ruby_mod_kit/node/statements_node.rbs +4 -0
  105. data/sig/generated/ruby_mod_kit/node/symbol_node.rbs +8 -3
  106. data/sig/generated/ruby_mod_kit/node/untyped_node.rbs +4 -0
  107. data/sig/generated/ruby_mod_kit/node/wrap.rbs +4 -0
  108. data/sig/generated/ruby_mod_kit/offset_diff.rbs +6 -0
  109. data/sig/generated/ruby_mod_kit.rbs +31 -6
  110. metadata +15 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bb9b6cf5cb887308d1237eb07d40b4b2b2514173c5e76d19e13a27687f2c107f
4
- data.tar.gz: 418e2d01aec4c8f8b4f0b6241625a0b550aec118a3dbd0618987171bb270e4f7
3
+ metadata.gz: 7d1688dd299feefd22167740d43d09a691ba4e01359edbdfdcb81462ec7c4d47
4
+ data.tar.gz: 1ea7711fddb58f15c1257fb8a63595d300a7c45483af595f4defc48c5a842466
5
5
  SHA512:
6
- metadata.gz: 17a8efaedb26b0b3256fd0b24501298a1f56fdf4dc8d5c33adc8cb6005abf6c5fcca4c0d1d634b34784dd2528ec57c8d2effdaf4042bc522a15359c86b01b804
7
- data.tar.gz: 73758c1ef48bcb7884a6f37859115b952474084abca4b6560f7d21c5380ec4bece1f97e165e6ef27b8270b0f5209877f5b2b63f1cd408ed5b4b6f5cb517d8dc1
6
+ metadata.gz: fa6c821537ec79c43ed5b092f2a0044126c0b925bff381c33971c2462a0578e92b0f681d313d3053c0fbc688f13907a6b10180738fa075bc192e1b582c843479
7
+ data.tar.gz: a84c961311ae15bc60b8db3594a1f412ca7b1a71d4922707d271c7d3eba9338e91338c69f2414a04907c1bc1e2b76581d1298a3effd22706913d4731fe93b084
data/.ruby_mod_kit.yml CHANGED
@@ -3,3 +3,4 @@ features:
3
3
  - overload
4
4
  - type
5
5
  - type/rbs_inline
6
+ - type/yard
data/.yardopts ADDED
@@ -0,0 +1,3 @@
1
+ --tag rbs:rbs
2
+ --exclude lib/ruby_mod_kit/core_ext.rb
3
+ --exclude lib/internal/
data/README.md CHANGED
@@ -15,6 +15,95 @@ If bundler is not being used to manage dependencies, install the gem by executin
15
15
 
16
16
  ## Usage
17
17
 
18
+ ### as library
19
+
20
+ `RubyModKit.transpile` returns transpiled script.
21
+
22
+ ```
23
+ require "ruby_mod_kit"
24
+ eval(
25
+ RubyModKit.transpile(<<~RBM),
26
+ class Foo
27
+ getter @foo: Integer
28
+ def initialize(@foo)
29
+ end
30
+ end
31
+ RBM
32
+ )
33
+ p Foo.new(1).foo # => 1
34
+ ```
35
+
36
+ `require "ruby_mod_kit/core_ext/eval"` gives `RubyModKit.eval`.
37
+
38
+ ```
39
+ require "ruby_mod_kit/core_ext/eval"
40
+ RubyModKit.eval(<<~RBM)
41
+ class Foo
42
+ getter @foo: Integer
43
+ def initialize(@foo)
44
+ end
45
+ end
46
+ RBM
47
+ p Foo.new(1).foo # => 1
48
+ ```
49
+
50
+ `require "ruby_mod_kit/core_ext/load"` gives `RubyModKit.load` and `RubyModKit.require`.
51
+
52
+ ```
53
+ require "ruby_mod_kit/core_ext/load"
54
+ require "tmpdir"
55
+
56
+ script = <<~RBM
57
+ class Foo
58
+ getter @foo: Integer
59
+ def initialize(@foo)
60
+ end
61
+ end
62
+ RBM
63
+
64
+ Dir.mktmpdir do |tmpdir|
65
+ File.write("#{tmpdir}/some_lib.rbm", script)
66
+ $LOAD_PATH << tmpdir
67
+ RubyModKit.require "some_lib"
68
+ end
69
+
70
+ p Foo.new(1).foo # => 1
71
+ ```
72
+
73
+ And `require "ruby_mod_kit/core_ext"` is more powerfull but dangerous. It overwrites `eval`, `require` and `load`.
74
+
75
+ ```
76
+ require "ruby_mod_kit/core_ext"
77
+ eval(<<~RBM)
78
+ class Foo
79
+ getter @foo: Integer
80
+ def initialize(@foo)
81
+ end
82
+ end
83
+ RBM
84
+ p Foo.new(1).foo # => 1
85
+ ```
86
+
87
+ ```
88
+ require "ruby_mod_kit/core_ext"
89
+ require "tmpdir"
90
+
91
+ script = <<~RBM
92
+ class Foo
93
+ getter @foo: Integer
94
+ def initialize(@foo)
95
+ end
96
+ end
97
+ RBM
98
+
99
+ Dir.mktmpdir do |tmpdir|
100
+ File.write("#{tmpdir}/some_lib.rbm", script)
101
+ $LOAD_PATH << tmpdir
102
+ require "some_lib"
103
+ end
104
+
105
+ p Foo.new(1).foo # => 1
106
+ ```
18
107
  ### as command line tool
19
108
 
20
109
  #### `transpile`
data/examples/user.rb CHANGED
@@ -50,25 +50,13 @@ class Pos
50
50
  # | (Integer) -> Pos
51
51
  def *(*args)
52
52
  case args
53
- in [Pos]
54
- _mul__overload0(*args)
55
- in [Integer]
56
- _mul__overload1(*args)
53
+ in [Pos => other]
54
+ (@x * other.x) + (@y * other.y) + (@z * other.z)
55
+ in [Integer => n]
56
+ Pos.new(@x * n, @y * n, @z * n)
57
57
  end
58
58
  end
59
59
 
60
- # @rbs other: Pos
61
- # @rbs return: Integer
62
- def _mul__overload0(other)
63
- (@x * other.x) + (@y * other.y) + (@z * other.z)
64
- end
65
-
66
- # @rbs n: Integer
67
- # @rbs return: Pos
68
- def _mul__overload1(n)
69
- Pos.new(@x * n, @y * n, @z * n)
70
- end
71
-
72
60
  # @rbs return: String
73
61
  def to_s
74
62
  "#<Pos: (#{@x}, #{@y}, #{@z})>"
@@ -11,6 +11,8 @@ module RubyModKit
11
11
  desc "exec", "execute rbm file"
12
12
  # @rbs *args: String
13
13
  # @rbs return: void
14
+ # @param args [String]
15
+ # @return [void]
14
16
  def exec(*args)
15
17
  RubyModKit.execute_file(*args, config: config)
16
18
  end
@@ -19,6 +21,8 @@ module RubyModKit
19
21
  method_option :output, type: :string
20
22
  # @rbs *args: String
21
23
  # @rbs return: void
24
+ # @param args [String]
25
+ # @return [void]
22
26
  def transpile(*args)
23
27
  output = case options[:output]
24
28
  when nil, "-", "/dev/stdout"
@@ -37,6 +41,7 @@ module RubyModKit
37
41
  private
38
42
 
39
43
  # @rbs return: Config | nil
44
+ # @return [Config, nil]
40
45
  def config
41
46
  if options[:config]
42
47
  config_path = options[:config]
@@ -15,6 +15,8 @@ module RubyModKit
15
15
 
16
16
  # @rbs features: Array[String]
17
17
  # @rbs return: void
18
+ # @param features [Array<String>]
19
+ # @return [void]
18
20
  def initialize(features: DEFAULT_FEATURES)
19
21
  @features = features.sort.map do |feature_name|
20
22
  raise ArgumentError, "invalid feature: #{feature_name}" if feature_name.include?(".")
@@ -29,8 +31,11 @@ module RubyModKit
29
31
 
30
32
  class << self
31
33
  # @rbs path: String
32
- # @rbs if_none: nil | Symbol
34
+ # @rbs if_none: Symbol | nil
33
35
  # @rbs return: Config | nil
36
+ # @param path [String]
37
+ # @param if_none [Symbol, nil]
38
+ # @return [Config, nil]
34
39
  def load(path, if_none: nil)
35
40
  return load(File.join(path, ".ruby_mod_kit.yml"), if_none: if_none) if File.directory?(path)
36
41
 
@@ -6,25 +6,28 @@ require "ruby_mod_kit"
6
6
 
7
7
  # Define RubyMotKit.eval
8
8
  module RubyModKit
9
+ # the namespace for language core extensions
9
10
  module CoreExt
10
11
  # the extension for eval
11
12
  module Eval
12
13
  module_function
13
14
 
14
15
  # @rbs expr: String
15
- # @rbs *rest: Object
16
+ # @rbs binding: Binding
17
+ # @rbs fname: String
18
+ # @rbs lineno: Integer
16
19
  # @rbs transpile: bool
17
20
  # @rbs return: Object
18
- def eval(expr, *rest, transpile: true)
19
- if transpile
20
- fname = rest[1].is_a?(String) ? rest[1] : "(eval)"
21
- expr = RubyModKit.transpile(expr, filename: fname)
22
- end
21
+ # @param expr [String]
22
+ # @param binding [Binding]
23
+ # @param fname [String]
24
+ # @param lineno [Integer]
25
+ # @param transpile [Boolean]
26
+ # @return [Object]
27
+ def eval(expr, binding = TOPLEVEL_BINDING, fname = "(eval)", lineno = 1, transpile: true)
28
+ expr = RubyModKit.transpile(expr, filename: fname) if transpile
23
29
 
24
- case rest
25
- in [] | [Binding] | [Binding, String] | [Binding, String, Integer]
26
- super(expr, *rest)
27
- end
30
+ super(expr, binding, fname, lineno)
28
31
  end
29
32
  end
30
33
  end
@@ -17,6 +17,9 @@ module RubyModKit
17
17
  # @rbs path: String
18
18
  # @rbs wrap: bool
19
19
  # @rbs return: bool
20
+ # @param path [String]
21
+ # @param wrap [Boolean]
22
+ # @return [Boolean]
20
23
  def load(path, wrap = false) # rubocop:disable Style/OptionalBooleanParameter
21
24
  return super unless path.end_with?(".rbm")
22
25
 
@@ -27,6 +30,8 @@ module RubyModKit
27
30
 
28
31
  # @rbs path: String
29
32
  # @rbs return: bool
33
+ # @param path [String]
34
+ # @return [Boolean]
30
35
  def require(path)
31
36
  require_path = Load.require_path(path)
32
37
  return super unless require_path&.end_with?(".rbm")
@@ -39,11 +44,13 @@ module RubyModKit
39
44
 
40
45
  class << self
41
46
  # @rbs return: Array[String]
47
+ # @return [Array<String>]
42
48
  def loaded_features
43
49
  $LOADED_FEATURES
44
50
  end
45
51
 
46
52
  # @rbs return: Array[String]
53
+ # @return [Array<String>]
47
54
  def load_path
48
55
  $LOAD_PATH
49
56
  end
@@ -51,6 +58,9 @@ module RubyModKit
51
58
  # @rbs path: String
52
59
  # @rbs expanded: bool
53
60
  # @rbs return: String | nil
61
+ # @param path [String]
62
+ # @param expanded [Boolean]
63
+ # @return [String, nil]
54
64
  def require_path(path, expanded: false)
55
65
  if !expanded && !File.absolute_path?(path)
56
66
  return load_path.each.lazy.map { require_path(File.join(_1, path), expanded: true) }.find(&:itself)
@@ -6,6 +6,7 @@ module RubyModKit
6
6
  # the base class of corrector
7
7
  class Corrector
8
8
  # @rbs return: Array[Symbol]
9
+ # @return [Array<Symbol>]
9
10
  def correctable_error_types
10
11
  []
11
12
  end
@@ -13,8 +14,15 @@ module RubyModKit
13
14
  # @rbs _parse_error: Prism::ParseError
14
15
  # @rbs _generation: Generation
15
16
  # @rbs return: void
17
+ # @param _parse_error [Prism::ParseError]
18
+ # @param _generation [Generation]
19
+ # @return [void]
16
20
  def correct(_parse_error, _generation)
17
21
  raise RubyModKit::Error, "Unexpected type #{self.class}"
18
22
  end
23
+
24
+ # @rbs return: void
25
+ # @return [void]
26
+ def setup; end
19
27
  end
20
28
  end
@@ -5,13 +5,15 @@
5
5
  module RubyModKit
6
6
  # the class to manege parse error correctors
7
7
  class CorrectorManager
8
- # @rbs @previous_error_messages: Array[String]
8
+ # @rbs @previous_source: String
9
9
  # @rbs @correctors_error_map: Hash[Symbol, Array[Corrector]]
10
10
 
11
11
  # @rbs features: Array[Feature]
12
12
  # @rbs return: void
13
+ # @param features [Array<Feature>]
14
+ # @return [void]
13
15
  def initialize(features)
14
- @previous_error_messages = []
16
+ @previous_source = +""
15
17
  @correctors_error_map = {}
16
18
  features.each do |feature|
17
19
  feature.create_correctors.each do |corrector|
@@ -24,11 +26,17 @@ module RubyModKit
24
26
 
25
27
  # @rbs generation: Generation
26
28
  # @rbs return: bool
29
+ # @param generation [Generation]
30
+ # @return [Boolean]
27
31
  def perform(generation)
28
32
  return true if generation.errors.empty?
29
33
 
30
34
  check_prev_errors(generation)
31
- @previous_error_messages = generation.errors.map(&:message)
35
+ @previous_source = generation.script.dup
36
+
37
+ @correctors_error_map.each_value do |correctors|
38
+ correctors.each(&:setup)
39
+ end
32
40
 
33
41
  generation.errors.each do |parse_error|
34
42
  correctors = @correctors_error_map[parse_error.type] || next
@@ -42,17 +50,19 @@ module RubyModKit
42
50
 
43
51
  # @rbs generation: Generation
44
52
  # @rbs return: void
53
+ # @param generation [Generation]
54
+ # @return [void]
45
55
  def check_prev_errors(generation)
46
- return if @previous_error_messages.empty?
56
+ return if @previous_source.empty?
47
57
  return if generation.errors.empty?
48
- return if @previous_error_messages != generation.errors.map(&:message)
58
+ return if @previous_source != generation.script
49
59
 
50
60
  message = +""
51
61
  generation.errors.each do |parse_error|
52
62
  message << "\n" unless message.empty?
53
63
  message << "#{generation.name}:#{parse_error.location.start_line}:#{parse_error.message} "
54
64
  message << "(#{parse_error.type})"
55
- line = generation.lines[parse_error.location.start_line - 1]
65
+ line = generation.line(parse_error)
56
66
  if line
57
67
  message << "\n#{line.chomp}\n"
58
68
  message << "#{" " * parse_error.location.start_column}^#{"~" * [parse_error.location.length - 1, 0].max}"
@@ -8,6 +8,7 @@ module RubyModKit
8
8
  # the class to correct `def foo(@bar) ...` -> `def foo(bar) ...`
9
9
  class InstanceVariableParameterCorrector < Corrector
10
10
  # @rbs return: Array[Symbol]
11
+ # @return [Array<Symbol>]
11
12
  def correctable_error_types
12
13
  %i[argument_formal_ivar]
13
14
  end
@@ -15,6 +16,9 @@ module RubyModKit
15
16
  # @rbs parse_error: Prism::ParseError
16
17
  # @rbs generation: Generation
17
18
  # @rbs return: void
19
+ # @param parse_error [Prism::ParseError]
20
+ # @param generation [Generation]
21
+ # @return [void]
18
22
  def correct(parse_error, generation)
19
23
  src_offset = parse_error.location.start_offset
20
24
 
@@ -9,8 +9,10 @@ module RubyModKit
9
9
  class InstanceVariableParameterMission < Mission
10
10
  # @rbs generation: Generation
11
11
  # @rbs return: bool
12
+ # @param generation [Generation]
13
+ # @return [Boolean]
12
14
  def perform(generation)
13
- generation.memo_pad.parameters_memo.each_value do |parameter_memo|
15
+ generation.memo_pad.each_parameter_memo do |parameter_memo|
14
16
  next unless parameter_memo.ivar_parameter
15
17
 
16
18
  offset = parameter_memo.offset
@@ -7,6 +7,7 @@ module RubyModKit
7
7
  # namespace for instance_variable parameter feature
8
8
  class InstanceVariableParameter < Feature
9
9
  # @rbs return: Array[Corrector]
10
+ # @return [Array<Corrector>]
10
11
  def create_correctors
11
12
  [
12
13
  InstanceVariableParameterCorrector.new,
@@ -14,6 +15,7 @@ module RubyModKit
14
15
  end
15
16
 
16
17
  # @rbs return: Array[Mission]
18
+ # @return [Array<Mission>]
17
19
  def create_missions
18
20
  [
19
21
  InstanceVariableParameterMission.new,
@@ -14,6 +14,7 @@ module RubyModKit
14
14
  }.freeze #: Hash[Symbol, String]
15
15
 
16
16
  # @rbs return: void
17
+ # @return [void]
17
18
  def initialize
18
19
  super
19
20
  @modified = false
@@ -21,8 +22,19 @@ module RubyModKit
21
22
 
22
23
  # @rbs generation: Generation
23
24
  # @rbs return: bool
25
+ # @param generation [Generation]
26
+ # @return [Boolean]
24
27
  def perform(generation)
25
- return true if @modified
28
+ if @modified
29
+ generation.memo_pad.overloads_memo.each_value do |overload_memo|
30
+ overload_memo.correct_offset(generation.root_node)
31
+ def_node = generation.root_node.def_node_at(overload_memo.offset)
32
+ raise RubyModKit::Error unless def_node.is_a?(Node::DefNode)
33
+
34
+ generation[def_node.end_offset, 0] = "\n" if def_node.parent.children[-1].offset > def_node.end_offset
35
+ end
36
+ return true
37
+ end
26
38
 
27
39
  method_memo_groups = generation.memo_pad.methods_memo.each_value.group_by do |method_memo|
28
40
  [generation.root_node.def_parent_node_at(method_memo.offset), method_memo.name]
@@ -37,9 +49,8 @@ module RubyModKit
37
49
  raise RubyModKit::Error unless first_def_node.is_a?(Node::DefNode)
38
50
  raise RubyModKit::Error unless name.is_a?(Symbol)
39
51
 
40
- start_line = first_def_node.location.start_line - 1
41
- indent = generation.lines[start_line][/\A */] || ""
42
- src_offset = generation.offsets[start_line]
52
+ indent = generation.line_indent(first_def_node)
53
+ src_offset = generation.line_offset(first_def_node) || raise(RubyModKit::Error)
43
54
  script = +""
44
55
 
45
56
  overload_memo = generation.memo_pad.overload_memo(first_method_memo.offset, name)
@@ -51,18 +62,38 @@ module RubyModKit
51
62
  end
52
63
 
53
64
  script << "def #{name}(*args)\n case args\n"
54
- overload_prefix = +"#{OVERLOAD_METHOD_MAP[name] || name}_"
55
- method_memos.each_with_index do |method_memo, i|
56
- overload_name = "#{overload_prefix}_overload#{i}"
65
+ method_memos.each do |method_memo|
57
66
  def_node = generation.root_node.def_node_at(method_memo.offset)
58
- raise RubyModKit::Error if !def_node || !def_node.is_a?(Node::DefNode)
67
+ body_node = def_node&.body_node
68
+ raise RubyModKit::Error unless def_node
69
+
70
+ def_start_offset = generation.line_offset(def_node) || raise(RubyModKit::Error)
71
+ def_end_offset = generation.end_line_offset(def_node) || raise(RubyModKit::Error)
72
+ def_end_offset += generation[def_end_offset..][/.*\n*/]&.size || 0
73
+ generation[def_start_offset, def_end_offset - def_start_offset] = ""
74
+ generation.memo_pad.delete(method_memo)
75
+
76
+ params = method_memo.parameters.map { |param| "#{param.type} => #{param.name}" }
77
+ script << " in [#{params.join(", ")}]\n"
78
+
79
+ body = nil
80
+ case body_node
81
+ when Node::StatementsNode
82
+ src_indent = generation.line_indent(body_node)
83
+ body = "#{src_indent}#{body_node.slice}\n".gsub(/^#{src_indent}/, " ")
84
+ when Node::BeginNode
85
+ src_indent = generation.line_indent(body_node)
86
+ src_line_offset = generation.line_offset(body_node.children[0]) || raise(RubyModKit::Error)
87
+ body = body_node.slice[(src_line_offset - body_node.offset)..]
88
+ body = "#{src_indent}begin\n#{body}\n".gsub(/^#{src_indent}/, " ")
89
+ when nil
90
+ body = ""
91
+ end
92
+ raise RubyModKit::Error unless body
59
93
 
60
- name_loc = def_node.name_loc
61
- generation[name_loc.start_offset, name_loc.length] = overload_name
62
- script << " in [#{method_memo.parameters.map(&:type).join(", ")}]\n"
63
- script << " #{overload_name}(*args)\n"
94
+ script << body
64
95
  end
65
- script << " end\nend\n\n"
96
+ script << " end\nend\n"
66
97
 
67
98
  script.gsub!(/^(?=.)/, indent)
68
99
  generation[src_offset, 0] = script
@@ -7,6 +7,7 @@ module RubyModKit
7
7
  # namespace for overload feature
8
8
  class Overload < Feature
9
9
  # @rbs return: Array[Mission]
10
+ # @return [Array<Mission>]
10
11
  def create_missions
11
12
  [
12
13
  OverloadMission.new,
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module RubyModKit
6
+ class Feature
7
+ class Type
8
+ module Check
9
+ # The mission to add magic comment
10
+ class AddArgumentsCheckerMission < Mission
11
+ # @rbs generation: Generation
12
+ # @rbs return: bool
13
+ # @param generation [Generation]
14
+ # @return [Boolean]
15
+ def perform(generation)
16
+ # reload if line break is added
17
+ line_break_added = false
18
+
19
+ generation.memo_pad.methods_memo.each do |offset, method_memo|
20
+ def_node = generation.root_node.def_node_at(offset)
21
+ raise RubyModKit::Error, "DefNode not found" unless def_node
22
+ next if method_memo.parameters.empty?
23
+
24
+ def_line = generation.line(def_node.location.start_line - 1)
25
+ def_indent = def_line[/\A\s*/] || ""
26
+
27
+ location = def_node.body_location || def_node.end_keyword_loc
28
+ next unless location
29
+
30
+ def_right_loc = def_node.rparen_loc || def_node.name_loc
31
+ offset = location.start_offset - location.start_column
32
+ indent = "#{def_indent} "
33
+ if location.start_line == def_right_loc.end_line
34
+ between_def_and_loc = generation[def_right_loc.end_offset...location.start_offset]
35
+ length = between_def_and_loc[/\A[ ^t]*;[ ^t]*\z/]&.length
36
+ if length
37
+ line_break_added = true
38
+ generation[def_right_loc.end_offset, length] = "\n#{def_indent}"
39
+ end
40
+ end
41
+ next if line_break_added
42
+
43
+ method_memo.parameters.each do |parameter_memo|
44
+ next if parameter_memo.untyped? || !parameter_memo.name
45
+ next if parameter_memo.qualifier # TODO: qualifier support
46
+
47
+ type = parameter_memo.type
48
+ type = type.gsub(/\[([^\[\]]+)\]/, "") # TODO: type variable support
49
+ generation[offset, 0] = "#{indent}#{parameter_memo.name} => #{type}\n"
50
+ end
51
+ end
52
+ !line_break_added
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module RubyModKit
6
+ class Feature
7
+ class Type
8
+ # namespace for type checker
9
+ module Check
10
+ # namespace for arguments type checker
11
+ class Arguments < Feature
12
+ # @rbs return: Array[Mission]
13
+ # @return [Array<Mission>]
14
+ def create_missions
15
+ [
16
+ AddArgumentsCheckerMission.new,
17
+ ]
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ require_relative "arguments/add_arguments_checker_mission"
@@ -9,9 +9,10 @@ module RubyModKit
9
9
  class InstanceVariableColonCorrector < Corrector
10
10
  VISIBILITIES = %i[private public protected].freeze #: Array[Symbol]
11
11
  ATTR_PATTERNS = %i[attr_reader reader getter attr_writer writer setter attr_accessor accessor property].freeze #: Array[Symbol]
12
- REGEXP = /(\A\s*)(?:(#{VISIBILITIES.join("|")}) )?(?:(#{ATTR_PATTERNS.join("|")}) )?@(\w*)\s*:\s*(.*)\n/.freeze #: Regexp
12
+ REGEXP = /(\A\s*)(?:(#{VISIBILITIES.join("|")}) )?(?:(#{ATTR_PATTERNS.join("|")}) )?@(\w*)\s*:\s*(.*)\n(\n+)?/.freeze #: Regexp
13
13
 
14
14
  # @rbs return: Array[Symbol]
15
+ # @return [Array<Symbol>]
15
16
  def correctable_error_types
16
17
  %i[unexpected_token_ignore]
17
18
  end
@@ -19,14 +20,20 @@ module RubyModKit
19
20
  # @rbs parse_error: Prism::ParseError
20
21
  # @rbs generation: Generation
21
22
  # @rbs return: void
23
+ # @param parse_error [Prism::ParseError]
24
+ # @param generation [Generation]
25
+ # @return [void]
22
26
  def correct(parse_error, generation)
23
27
  return if parse_error.location.slice != ":"
24
28
 
25
- def_parent_node = generation.root_node.statements_node_at(parse_error.location.start_offset)&.parent
29
+ def_parent_node = generation.root_node.def_parent_node_at(
30
+ parse_error.location.start_offset,
31
+ allowed: [Node::CallNode, Node::UntypedNode, Node::StatementsNode],
32
+ )
26
33
  return unless def_parent_node.is_a?(Node::DefParentNode)
27
34
 
28
- line = generation.line(parse_error)
29
- line_offset = generation.src_offset(parse_error) || return
35
+ line_offset = generation.line_offset(parse_error) || return
36
+ line = generation[line_offset..]
30
37
  return if line !~ REGEXP
31
38
 
32
39
  length = ::Regexp.last_match(0)&.length
@@ -35,6 +42,7 @@ module RubyModKit
35
42
  attr_kind = ::Regexp.last_match(3)
36
43
  ivar_name = ::Regexp.last_match(4)
37
44
  type = ::Regexp.last_match(5)
45
+ separator = ::Regexp.last_match(6)
38
46
  return if !length || !indent || !ivar_name || !type
39
47
 
40
48
  ivar_memo = generation.memo_pad.def_parent_memo(def_parent_node).ivar_memo(ivar_name.to_sym)
@@ -43,6 +51,7 @@ module RubyModKit
43
51
  ivar_memo.indent = indent
44
52
  ivar_memo.attr_kind = attr_kind if attr_kind
45
53
  ivar_memo.visibility = visibility.to_sym if visibility
54
+ ivar_memo.separator = separator if separator
46
55
 
47
56
  generation[line_offset, length] = ""
48
57
  end