ruby_mod_kit 0.0.3 → 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 (72) 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/corrector.rb +1 -3
  6. data/lib/ruby_mod_kit/corrector_manager.rb +11 -15
  7. data/lib/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_corrector.rb +5 -7
  8. data/lib/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_mission.rb +4 -11
  9. data/lib/ruby_mod_kit/feature/overload/overload_mission.rb +8 -11
  10. data/lib/ruby_mod_kit/feature/type/instance_variable_colon_corrector.rb +13 -10
  11. data/lib/ruby_mod_kit/feature/type/parameter_arrow_corrector.rb +9 -15
  12. data/lib/ruby_mod_kit/feature/type/rbs_inline/add_magic_comment_mission.rb +49 -0
  13. data/lib/ruby_mod_kit/feature/type/rbs_inline/type_attr_mission.rb +12 -7
  14. data/lib/ruby_mod_kit/feature/type/rbs_inline/type_instance_variable_mission.rb +5 -7
  15. data/lib/ruby_mod_kit/feature/type/rbs_inline/type_overload_mission.rb +6 -8
  16. data/lib/ruby_mod_kit/feature/type/rbs_inline/type_parameter_mission.rb +6 -8
  17. data/lib/ruby_mod_kit/feature/type/rbs_inline/type_return_mission.rb +5 -7
  18. data/lib/ruby_mod_kit/feature/type/rbs_inline.rb +3 -0
  19. data/lib/ruby_mod_kit/feature/type/return_value_colon_corrector.rb +4 -6
  20. data/lib/ruby_mod_kit/feature/type/type_attr_mission.rb +10 -8
  21. data/lib/ruby_mod_kit/feature.rb +0 -6
  22. data/lib/ruby_mod_kit/generation.rb +29 -20
  23. data/lib/ruby_mod_kit/memo/ivar_memo.rb +2 -0
  24. data/lib/ruby_mod_kit/memo/overload_memo.rb +1 -0
  25. data/lib/ruby_mod_kit/memo.rb +0 -2
  26. data/lib/ruby_mod_kit/memo_pad.rb +3 -0
  27. data/lib/ruby_mod_kit/mission.rb +1 -4
  28. data/lib/ruby_mod_kit/node/base_node.rb +28 -10
  29. data/lib/ruby_mod_kit/node/call_node.rb +1 -1
  30. data/lib/ruby_mod_kit/node/def_node.rb +1 -1
  31. data/lib/ruby_mod_kit/node/def_parent_node.rb +13 -6
  32. data/lib/ruby_mod_kit/node/parameter_node.rb +1 -1
  33. data/lib/ruby_mod_kit/node/program_node.rb +6 -1
  34. data/lib/ruby_mod_kit/node/statements_node.rb +1 -1
  35. data/lib/ruby_mod_kit/node/symbol_node.rb +2 -1
  36. data/lib/ruby_mod_kit/node/untyped_node.rb +1 -1
  37. data/lib/ruby_mod_kit/node.rb +0 -2
  38. data/lib/ruby_mod_kit/version.rb +1 -1
  39. data/lib/ruby_mod_kit.rb +11 -6
  40. data/ruby_mod_kit.gemspec +7 -1
  41. data/sig/generated/ruby_mod_kit/cli.rbs +5 -0
  42. data/sig/generated/ruby_mod_kit/config.rbs +21 -0
  43. data/sig/generated/ruby_mod_kit/corrector.rbs +1 -3
  44. data/sig/generated/ruby_mod_kit/corrector_manager.rbs +2 -6
  45. data/sig/generated/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_corrector.rbs +1 -3
  46. data/sig/generated/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_mission.rbs +1 -8
  47. data/sig/generated/ruby_mod_kit/feature/overload/overload_mission.rbs +1 -4
  48. data/sig/generated/ruby_mod_kit/feature/type/instance_variable_colon_corrector.rbs +7 -3
  49. data/sig/generated/ruby_mod_kit/feature/type/parameter_arrow_corrector.rbs +3 -9
  50. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/add_magic_comment_mission.rbs +21 -0
  51. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_attr_mission.rbs +1 -4
  52. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_instance_variable_mission.rbs +1 -4
  53. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_overload_mission.rbs +1 -4
  54. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_parameter_mission.rbs +1 -4
  55. data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_return_mission.rbs +1 -4
  56. data/sig/generated/ruby_mod_kit/feature/type/return_value_colon_corrector.rbs +1 -3
  57. data/sig/generated/ruby_mod_kit/feature/type/type_attr_mission.rbs +3 -4
  58. data/sig/generated/ruby_mod_kit/feature.rbs +0 -4
  59. data/sig/generated/ruby_mod_kit/generation.rbs +21 -5
  60. data/sig/generated/ruby_mod_kit/memo/ivar_memo.rbs +4 -0
  61. data/sig/generated/ruby_mod_kit/memo/overload_memo.rbs +2 -0
  62. data/sig/generated/ruby_mod_kit/memo_pad.rbs +4 -0
  63. data/sig/generated/ruby_mod_kit/mission.rbs +1 -4
  64. data/sig/generated/ruby_mod_kit/node/base_node.rbs +17 -7
  65. data/sig/generated/ruby_mod_kit/node/def_parent_node.rbs +5 -0
  66. data/sig/generated/ruby_mod_kit/node/program_node.rbs +3 -0
  67. data/sig/generated/ruby_mod_kit/node/symbol_node.rbs +2 -0
  68. data/sig/generated/ruby_mod_kit.rbs +6 -3
  69. data/sig/yaml.rbs +3 -0
  70. metadata +9 -5
  71. data/sig/generated/ruby_mod_kit/memo.rbs +0 -7
  72. data/sig/generated/ruby_mod_kit/node.rbs +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 36509ee4c00db1106b7447ba1d4fe09ee2fd2a8f8ce763c40b1da185f19cfc61
4
- data.tar.gz: eccbdb68bb6159aa95c7fda5d171e4089b9dfa9b262ef136caf019fa3c339d7f
3
+ metadata.gz: bb9b6cf5cb887308d1237eb07d40b4b2b2514173c5e76d19e13a27687f2c107f
4
+ data.tar.gz: 418e2d01aec4c8f8b4f0b6241625a0b550aec118a3dbd0618987171bb270e4f7
5
5
  SHA512:
6
- metadata.gz: a8b12f06259193345becd29a14a1c6397481c41b390daed390cf4ed0bc7016afe0fbcf9ba95a9c3639b37150c98791d3e501cf2490725bfc5cf3c405fdc99f94
7
- data.tar.gz: 684d9b858ac50e78b40f92a2d1cb8ddaafb99983bbdafc7788d786878af5b03c2187995bbe312de59495c9e4f796c352a9e203428d91018075a88791a79320eb
6
+ metadata.gz: 17a8efaedb26b0b3256fd0b24501298a1f56fdf4dc8d5c33adc8cb6005abf6c5fcca4c0d1d634b34784dd2528ec57c8d2effdaf4042bc522a15359c86b01b804
7
+ data.tar.gz: 73758c1ef48bcb7884a6f37859115b952474084abca4b6560f7d21c5380ec4bece1f97e165e6ef27b8270b0f5209877f5b2b63f1cd408ed5b4b6f5cb517d8dc1
data/.ruby_mod_kit.yml ADDED
@@ -0,0 +1,5 @@
1
+ features:
2
+ - instance_variable_parameter
3
+ - overload
4
+ - type
5
+ - type/rbs_inline
@@ -12,7 +12,7 @@ module RubyModKit
12
12
  # @rbs *args: String
13
13
  # @rbs return: void
14
14
  def exec(*args)
15
- RubyModKit.execute_file(*args)
15
+ RubyModKit.execute_file(*args, config: config)
16
16
  end
17
17
 
18
18
  desc "transpile", "transpile rbm files"
@@ -28,9 +28,24 @@ module RubyModKit
28
28
  else
29
29
  options[:output]
30
30
  end
31
+ config = self.config
31
32
  args.each do |path|
32
- RubyModKit.transpile_file(path, output: output || RubyModKit.rb_path(path))
33
+ RubyModKit.transpile_file(path, output: output || RubyModKit.rb_path(path), config: config)
33
34
  end
34
35
  end
36
+
37
+ private
38
+
39
+ # @rbs return: Config | nil
40
+ def config
41
+ if options[:config]
42
+ config_path = options[:config]
43
+ if_none = :raise
44
+ else
45
+ config_path = "."
46
+ if_none = nil
47
+ end
48
+ Config.load(config_path, if_none: if_none)
49
+ end
35
50
  end
36
51
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ require "yaml"
6
+
7
+ module RubyModKit
8
+ # config class
9
+ class Config
10
+ # @rbs @features: Array[Config]
11
+
12
+ attr_reader :features #: Array[Config]
13
+
14
+ DEFAULT_FEATURES = %w[instance_variable_parameter overload type type/rbs_inline].freeze #: Array[String]
15
+
16
+ # @rbs features: Array[String]
17
+ # @rbs return: void
18
+ def initialize(features: DEFAULT_FEATURES)
19
+ @features = features.sort.map do |feature_name|
20
+ raise ArgumentError, "invalid feature: #{feature_name}" if feature_name.include?(".")
21
+
22
+ require "ruby_mod_kit/feature/#{feature_name}"
23
+ const_name = feature_name
24
+ .gsub(/[A-Za-z0-9]+/) { (::Regexp.last_match(0) || "").capitalize }
25
+ .gsub("_", "").gsub("/", "::")
26
+ Feature.const_get(const_name).new
27
+ end
28
+ end
29
+
30
+ class << self
31
+ # @rbs path: String
32
+ # @rbs if_none: nil | Symbol
33
+ # @rbs return: Config | nil
34
+ def load(path, if_none: nil)
35
+ return load(File.join(path, ".ruby_mod_kit.yml"), if_none: if_none) if File.directory?(path)
36
+
37
+ unless File.exist?(path)
38
+ case if_none
39
+ when nil
40
+ return nil
41
+ when :raise
42
+ raise LoadError, "Can't load #{path}"
43
+ else
44
+ raise ArgumentError, "unexpected if_none: #{if_none.inspect}"
45
+ end
46
+ end
47
+
48
+ options = YAML.safe_load(File.read(path), symbolize_names: true)
49
+ new(**options) if options.is_a?(Hash)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -12,10 +12,8 @@ module RubyModKit
12
12
 
13
13
  # @rbs _parse_error: Prism::ParseError
14
14
  # @rbs _generation: Generation
15
- # @rbs _root_node: Node::ProgramNode
16
- # @rbs _memo_pad: MemoPad
17
15
  # @rbs return: void
18
- def correct(_parse_error, _generation, _root_node, _memo_pad)
16
+ def correct(_parse_error, _generation)
19
17
  raise RubyModKit::Error, "Unexpected type #{self.class}"
20
18
  end
21
19
  end
@@ -23,20 +23,17 @@ module RubyModKit
23
23
  end
24
24
 
25
25
  # @rbs generation: Generation
26
- # @rbs root_node: Node::ProgramNode
27
- # @rbs parse_result: Prism::ParseResult
28
- # @rbs memo_pad: MemoPad
29
26
  # @rbs return: bool
30
- def perform(generation, root_node, parse_result, memo_pad)
31
- return true if parse_result.errors.empty?
27
+ def perform(generation)
28
+ return true if generation.errors.empty?
32
29
 
33
- check_prev_errors(generation, parse_result)
34
- @previous_error_messages = parse_result.errors.map(&:message)
30
+ check_prev_errors(generation)
31
+ @previous_error_messages = generation.errors.map(&:message)
35
32
 
36
- parse_result.errors.each do |parse_error|
33
+ generation.errors.each do |parse_error|
37
34
  correctors = @correctors_error_map[parse_error.type] || next
38
35
  correctors.each do |corrector|
39
- corrector.correct(parse_error, generation, root_node, memo_pad)
36
+ corrector.correct(parse_error, generation)
40
37
  end
41
38
  end
42
39
 
@@ -44,19 +41,18 @@ module RubyModKit
44
41
  end
45
42
 
46
43
  # @rbs generation: Generation
47
- # @rbs parse_result: Prism::ParseResult
48
44
  # @rbs return: void
49
- def check_prev_errors(generation, parse_result)
45
+ def check_prev_errors(generation)
50
46
  return if @previous_error_messages.empty?
51
- return if parse_result.errors.empty?
52
- return if @previous_error_messages != parse_result.errors.map(&:message)
47
+ return if generation.errors.empty?
48
+ return if @previous_error_messages != generation.errors.map(&:message)
53
49
 
54
50
  message = +""
55
- parse_result.errors.each do |parse_error|
51
+ generation.errors.each do |parse_error|
56
52
  message << "\n" unless message.empty?
57
53
  message << "#{generation.name}:#{parse_error.location.start_line}:#{parse_error.message} "
58
54
  message << "(#{parse_error.type})"
59
- line = parse_result.source.lines[parse_error.location.start_line - 1]
55
+ line = generation.lines[parse_error.location.start_line - 1]
60
56
  if line
61
57
  message << "\n#{line.chomp}\n"
62
58
  message << "#{" " * parse_error.location.start_column}^#{"~" * [parse_error.location.length - 1, 0].max}"
@@ -14,26 +14,24 @@ module RubyModKit
14
14
 
15
15
  # @rbs parse_error: Prism::ParseError
16
16
  # @rbs generation: Generation
17
- # @rbs root_node: Node::ProgramNode
18
- # @rbs memo_pad: MemoPad
19
17
  # @rbs return: void
20
- def correct(parse_error, generation, root_node, memo_pad)
18
+ def correct(parse_error, generation)
21
19
  src_offset = parse_error.location.start_offset
22
20
 
23
21
  name = parse_error.location.slice[1..]
24
22
  raise RubyModKit::Error unless name
25
23
 
26
- parameter_position_node = root_node.node_at(src_offset)
24
+ parameter_position_node = generation.root_node.node_at(src_offset)
27
25
  raise RubyModKit::Error unless parameter_position_node
28
26
 
29
27
  generation[src_offset, parse_error.location.length] = name
30
- parameter_memo = memo_pad.parameter_memo(parameter_position_node)
28
+ parameter_memo = generation.memo_pad.parameter_memo(parameter_position_node)
31
29
  parameter_memo.ivar_parameter = true
32
30
 
33
31
  return unless parameter_memo.untyped?
34
32
 
35
- def_parent_node = root_node.def_parent_node_at(parse_error.location.start_offset) || return
36
- ivar_memo_type = memo_pad.def_parent_memo(def_parent_node).ivar_memo(name.to_sym).type || return
33
+ def_parent_node = generation.root_node.def_parent_node_at(parse_error.location.start_offset) || return
34
+ ivar_memo_type = generation.memo_pad.def_parent_memo(def_parent_node).ivar_memo(name.to_sym).type || return
37
35
  parameter_memo.type = ivar_memo_type
38
36
  end
39
37
  end
@@ -7,24 +7,17 @@ module RubyModKit
7
7
  class InstanceVariableParameter
8
8
  # The mission for instance variable arguments
9
9
  class InstanceVariableParameterMission < Mission
10
- # @rbs @assignment: String
11
-
12
- attr_reader :assignment #: String
13
-
14
10
  # @rbs generation: Generation
15
- # @rbs root_node: Node::ProgramNode
16
- # @rbs _parse_result: Prism::ParseResult
17
- # @rbs memo_pad: MemoPad
18
11
  # @rbs return: bool
19
- def perform(generation, root_node, _parse_result, memo_pad)
20
- memo_pad.parameters_memo.each_value do |parameter_memo|
12
+ def perform(generation)
13
+ generation.memo_pad.parameters_memo.each_value do |parameter_memo|
21
14
  next unless parameter_memo.ivar_parameter
22
15
 
23
16
  offset = parameter_memo.offset
24
- parameter_node = root_node.parameter_node_at(offset)
17
+ parameter_node = generation.root_node.parameter_node_at(offset)
25
18
  raise RubyModKit::Error unless parameter_node
26
19
 
27
- def_node = root_node.def_node_at(offset)
20
+ def_node = generation.root_node.def_node_at(offset)
28
21
  raise RubyModKit::Error, "DefNode not found" unless def_node
29
22
 
30
23
  def_body_location = def_node.body_location
@@ -20,15 +20,12 @@ module RubyModKit
20
20
  end
21
21
 
22
22
  # @rbs generation: Generation
23
- # @rbs root_node: Node::ProgramNode
24
- # @rbs parse_result: Prism::ParseResult
25
- # @rbs memo_pad: MemoPad
26
23
  # @rbs return: bool
27
- def perform(generation, root_node, parse_result, memo_pad)
24
+ def perform(generation)
28
25
  return true if @modified
29
26
 
30
- method_memo_groups = memo_pad.methods_memo.each_value.group_by do |method_memo|
31
- [root_node.def_parent_node_at(method_memo.offset), method_memo.name]
27
+ method_memo_groups = generation.memo_pad.methods_memo.each_value.group_by do |method_memo|
28
+ [generation.root_node.def_parent_node_at(method_memo.offset), method_memo.name]
32
29
  end
33
30
  method_memo_groups.each_value do |method_memos|
34
31
  next if method_memos.length <= 1
@@ -36,16 +33,16 @@ module RubyModKit
36
33
  @modified = true
37
34
  first_method_memo = method_memos.first
38
35
  name = first_method_memo.name
39
- first_def_node = root_node.def_node_at(first_method_memo.offset)
36
+ first_def_node = generation.root_node.def_node_at(first_method_memo.offset)
40
37
  raise RubyModKit::Error unless first_def_node.is_a?(Node::DefNode)
41
38
  raise RubyModKit::Error unless name.is_a?(Symbol)
42
39
 
43
40
  start_line = first_def_node.location.start_line - 1
44
- indent = parse_result.source.lines[start_line][/\A */] || ""
45
- src_offset = parse_result.source.offsets[start_line]
41
+ indent = generation.lines[start_line][/\A */] || ""
42
+ src_offset = generation.offsets[start_line]
46
43
  script = +""
47
44
 
48
- overload_memo = memo_pad.overload_memo(first_method_memo.offset, name)
45
+ overload_memo = generation.memo_pad.overload_memo(first_method_memo.offset, name)
49
46
 
50
47
  method_memos.each do |method_memo|
51
48
  type = method_memo.type
@@ -57,7 +54,7 @@ module RubyModKit
57
54
  overload_prefix = +"#{OVERLOAD_METHOD_MAP[name] || name}_"
58
55
  method_memos.each_with_index do |method_memo, i|
59
56
  overload_name = "#{overload_prefix}_overload#{i}"
60
- def_node = root_node.def_node_at(method_memo.offset)
57
+ def_node = generation.root_node.def_node_at(method_memo.offset)
61
58
  raise RubyModKit::Error if !def_node || !def_node.is_a?(Node::DefNode)
62
59
 
63
60
  name_loc = def_node.name_loc
@@ -7,6 +7,10 @@ module RubyModKit
7
7
  class Type
8
8
  # the class to correct `@var: Type` -> `# @rbs @var: Type`
9
9
  class InstanceVariableColonCorrector < Corrector
10
+ VISIBILITIES = %i[private public protected].freeze #: Array[Symbol]
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
13
+
10
14
  # @rbs return: Array[Symbol]
11
15
  def correctable_error_types
12
16
  %i[unexpected_token_ignore]
@@ -14,32 +18,31 @@ module RubyModKit
14
18
 
15
19
  # @rbs parse_error: Prism::ParseError
16
20
  # @rbs generation: Generation
17
- # @rbs root_node: Node::ProgramNode
18
- # @rbs memo_pad: MemoPad
19
21
  # @rbs return: void
20
- def correct(parse_error, generation, root_node, memo_pad)
22
+ def correct(parse_error, generation)
21
23
  return if parse_error.location.slice != ":"
22
24
 
23
- def_parent_node = root_node.statements_node_at(parse_error.location.start_offset)&.parent
25
+ def_parent_node = generation.root_node.statements_node_at(parse_error.location.start_offset)&.parent
24
26
  return unless def_parent_node.is_a?(Node::DefParentNode)
25
27
 
26
28
  line = generation.line(parse_error)
27
29
  line_offset = generation.src_offset(parse_error) || return
28
- attr_patterns = %i[attr_reader reader getter attr_writer writer setter attr_accessor accessor property]
29
- return if line !~ /(\A\s*)(?:(#{attr_patterns.join("|")}) )?@(\w*)\s*:\s*(.*)\n/
30
+ return if line !~ REGEXP
30
31
 
31
32
  length = ::Regexp.last_match(0)&.length
32
33
  indent = ::Regexp.last_match(1)
33
- attr_kind = ::Regexp.last_match(2)
34
- ivar_name = ::Regexp.last_match(3)
35
- type = ::Regexp.last_match(4)
34
+ visibility = ::Regexp.last_match(2)
35
+ attr_kind = ::Regexp.last_match(3)
36
+ ivar_name = ::Regexp.last_match(4)
37
+ type = ::Regexp.last_match(5)
36
38
  return if !length || !indent || !ivar_name || !type
37
39
 
38
- ivar_memo = memo_pad.def_parent_memo(def_parent_node).ivar_memo(ivar_name.to_sym)
40
+ ivar_memo = generation.memo_pad.def_parent_memo(def_parent_node).ivar_memo(ivar_name.to_sym)
39
41
  ivar_memo.type = type
40
42
  ivar_memo.offset = line_offset
41
43
  ivar_memo.indent = indent
42
44
  ivar_memo.attr_kind = attr_kind if attr_kind
45
+ ivar_memo.visibility = visibility.to_sym if visibility
43
46
 
44
47
  generation[line_offset, length] = ""
45
48
  end
@@ -14,17 +14,15 @@ module RubyModKit
14
14
 
15
15
  # @rbs parse_error: Prism::ParseError
16
16
  # @rbs generation: Generation
17
- # @rbs root_node: Node::ProgramNode
18
- # @rbs memo_pad: MemoPad
19
17
  # @rbs return: void
20
- def correct(parse_error, generation, root_node, memo_pad)
18
+ def correct(parse_error, generation)
21
19
  case parse_error.type
22
20
  when :unexpected_token_ignore
23
21
  return if parse_error.location.slice != "=>"
24
22
 
25
- remove_arrow_before_parameter(parse_error, generation, root_node, memo_pad)
23
+ remove_arrow_before_parameter(parse_error, generation)
26
24
  when :def_params_term_paren
27
- remove_arrow_after_quailifier(parse_error, generation, root_node, memo_pad)
25
+ remove_arrow_after_quailifier(parse_error, generation)
28
26
  when :argument_formal_constant
29
27
  wrap_parameter_type_for_next_parse(parse_error, generation)
30
28
  end
@@ -32,11 +30,9 @@ module RubyModKit
32
30
 
33
31
  # @rbs parse_error: Prism::ParseError
34
32
  # @rbs generation: Generation
35
- # @rbs root_node: Node::ProgramNode
36
- # @rbs memo_pad: MemoPad
37
33
  # @rbs return: void
38
- def remove_arrow_before_parameter(parse_error, generation, root_node, memo_pad)
39
- def_node = root_node.def_node_at(parse_error.location.start_offset) || return
34
+ def remove_arrow_before_parameter(parse_error, generation)
35
+ def_node = generation.root_node.def_node_at(parse_error.location.start_offset) || return
40
36
  def_parent_node = def_node.parent
41
37
  parameters_node, body_node, = def_node.children
42
38
  return if !def_parent_node || !parameters_node || !body_node
@@ -49,15 +45,13 @@ module RubyModKit
49
45
  parameter_type = generation[last_parameter_offset...right_offset] || raise(RubyModKit::Error)
50
46
  parameter_type = parameter_type.sub(/\s*=>\s*\z/, "")
51
47
  generation[last_parameter_offset, right_offset - last_parameter_offset] = ""
52
- memo_pad.parameter_memo(last_parameter_node).type = parameter_type
48
+ generation.memo_pad.parameter_memo(last_parameter_node).type = parameter_type
53
49
  end
54
50
 
55
51
  # @rbs parse_error: Prism::ParseError
56
52
  # @rbs generation: Generation
57
- # @rbs root_node: Node::ProgramNode
58
- # @rbs memo_pad: MemoPad
59
53
  # @rbs return: void
60
- def remove_arrow_after_quailifier(parse_error, generation, root_node, memo_pad)
54
+ def remove_arrow_after_quailifier(parse_error, generation)
61
55
  column = parse_error.location.start_column - 1
62
56
  return if column < 0
63
57
 
@@ -66,10 +60,10 @@ module RubyModKit
66
60
  length = ::Regexp.last_match(0)&.length || return
67
61
  type = ::Regexp.last_match(1) || return
68
62
  offset = parse_error.location.start_offset - 1
69
- parameter_position_node = root_node.node_at(offset + length) || return
63
+ parameter_position_node = generation.root_node.node_at(offset + length) || return
70
64
 
71
65
  generation[parse_error.location.start_offset, length - 1] = ""
72
- parameter_memo = memo_pad.parameter_memo(parameter_position_node)
66
+ parameter_memo = generation.memo_pad.parameter_memo(parameter_position_node)
73
67
  parameter_memo.type = type
74
68
  parameter_memo.qualifier = "*"
75
69
  end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module RubyModKit
6
+ class Feature
7
+ class Type
8
+ class RbsInline
9
+ # The mission to add magic comment
10
+ class AddMagicCommentMission < Mission
11
+ # @rbs @reloaded: bool
12
+
13
+ # @rbs return: void
14
+ def initialize
15
+ super
16
+ @reloaded = false
17
+ end
18
+
19
+ # @rbs generation: Generation
20
+ # @rbs return: bool
21
+ def perform(generation)
22
+ return true unless generation.memo_pad.flags[:rbs_annotated]
23
+
24
+ unless @reloaded
25
+ @reloaded = true
26
+ return false
27
+ end
28
+
29
+ offset = 0
30
+ separated = false
31
+ generation.lines.each do |line|
32
+ break if line =~ /^# @rbs/
33
+ break if line !~ /^#( rbs_inline: enabled)?|(^$)/
34
+ return true if ::Regexp.last_match(1)
35
+
36
+ separated = !::Regexp.last_match(2).nil?
37
+
38
+ offset += line.length
39
+ end
40
+ script = +""
41
+ script << "\n" unless separated
42
+ generation[offset, 0] = "# rbs_inline: enabled\n\n"
43
+ true
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -9,16 +9,20 @@ module RubyModKit
9
9
  # The mission for parameter types
10
10
  class TypeAttrMission < Mission
11
11
  # @rbs generation: Generation
12
- # @rbs root_node: Node::ProgramNode
13
- # @rbs _parse_result: Prism::ParseResult
14
- # @rbs memo_pad: MemoPad
15
12
  # @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|
13
+ def perform(generation)
14
+ generation.memo_pad.def_parents_memo.each_value do |def_parent_memo|
18
15
  ivars_memo = def_parent_memo.ivars_memo.dup
19
- def_parent_node = root_node.def_parent_node_at(def_parent_memo.offset) || raise(RubyModKit::Error)
16
+ def_parent_node = generation.root_node.def_parent_node_at(def_parent_memo.offset)
17
+ raise(RubyModKit::Error) unless def_parent_node
18
+
20
19
  def_parent_node.body_node&.children&.each do |call_node|
21
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
22
26
  next unless call_node.is_a?(Node::CallNode)
23
27
  next unless %i[attr_reader attr_writer attr_accessor].include?(call_node.name)
24
28
 
@@ -28,7 +32,8 @@ module RubyModKit
28
32
  name = argument_nodes[0].value || next
29
33
  ivar_memo = ivars_memo.delete(name) || next
30
34
  line = generation.line(call_node)
31
- length = line[/\A\s*(#{call_node.name}\s+:#{name})(?=\n\z)/, 1]&.length || next
35
+ length = line[/\A.*(#{call_node.name}\s+:#{name})(?=\n\z)/, 1]&.length || next
36
+ generation.memo_pad.flags[:rbs_annotated] = true
32
37
  generation[call_node.location.start_offset + length, 0] = " #: #{ivar_memo.type}"
33
38
  end
34
39
  end
@@ -9,16 +9,14 @@ module RubyModKit
9
9
  # The mission for instance variable types
10
10
  class TypeInstanceVariableMission < Mission
11
11
  # @rbs generation: Generation
12
- # @rbs root_node: Node::ProgramNode
13
- # @rbs parse_result: Prism::ParseResult
14
- # @rbs memo_pad: MemoPad
15
12
  # @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|
13
+ def perform(generation)
14
+ generation.memo_pad.def_parents_memo.each_value do |def_parent_memo|
18
15
  def_parent_memo.ivars_memo.each do |name, ivar_memo|
19
16
  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]
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
22
20
  generation[body_line_offset, 0] = "#{ivar_memo.indent}# @rbs @#{name}: #{ivar_memo.type}\n"
23
21
  end
24
22
  end
@@ -9,17 +9,14 @@ module RubyModKit
9
9
  # The mission for parameter types
10
10
  class TypeOverloadMission < Mission
11
11
  # @rbs generation: Generation
12
- # @rbs root_node: Node::ProgramNode
13
- # @rbs parse_result: Prism::ParseResult
14
- # @rbs memo_pad: MemoPad
15
12
  # @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)
13
+ def perform(generation)
14
+ generation.memo_pad.overloads_memo.each_value do |overload_memo|
15
+ overload_memo.correct_offset(generation.root_node)
19
16
  offset = overload_memo.offset
20
- def_node = root_node.def_node_at(offset) || raise(RubyModKit::Error)
17
+ def_node = generation.root_node.def_node_at(offset) || raise(RubyModKit::Error)
21
18
  start_line = def_node.location.start_line - 1
22
- indent = parse_result.source.lines[start_line][/\A */] || ""
19
+ indent = generation.lines[start_line][/\A */] || ""
23
20
  offset -= indent.length
24
21
 
25
22
  annotation = +""
@@ -32,6 +29,7 @@ module RubyModKit
32
29
  annotation << " (#{parameter_types.join(", ")}) -> #{return_type}\n"
33
30
  end
34
31
  annotation.gsub!(/^/, indent)
32
+ generation.memo_pad.flags[:rbs_annotated] = true
35
33
  generation[offset, 0] = annotation
36
34
  end
37
35
  true
@@ -9,24 +9,22 @@ module RubyModKit
9
9
  # The mission for parameter types
10
10
  class TypeParameterMission < Mission
11
11
  # @rbs generation: Generation
12
- # @rbs root_node: Node::ProgramNode
13
- # @rbs parse_result: Prism::ParseResult
14
- # @rbs memo_pad: MemoPad
15
12
  # @rbs return: bool
16
- def perform(generation, root_node, parse_result, memo_pad)
17
- memo_pad.parameters_memo.each do |offset, parameter_memo|
13
+ def perform(generation)
14
+ generation.memo_pad.parameters_memo.each do |offset, parameter_memo|
18
15
  next if parameter_memo.untyped?
19
16
 
20
- def_node = root_node.def_node_at(offset)
17
+ def_node = generation.root_node.def_node_at(offset)
21
18
  raise RubyModKit::Error, "DefNode not found" if !def_node || !def_node.is_a?(Node::DefNode)
22
19
 
23
- parameter_node = root_node.parameter_node_at(offset)
20
+ parameter_node = generation.root_node.parameter_node_at(offset)
24
21
  raise RubyModKit::Error, "ParameterNode not found" unless parameter_node
25
22
 
26
23
  type = parameter_memo.type
27
- src_offset = parse_result.source.offsets[def_node.location.start_line - 1]
24
+ src_offset = generation.offsets[def_node.location.start_line - 1]
28
25
  indent = def_node.offset - src_offset
29
26
  qualified_name = "#{parameter_memo.qualifier}#{parameter_node.name}"
27
+ generation.memo_pad.flags[:rbs_annotated] = true
30
28
  generation[src_offset, 0] = "#{" " * indent}# @rbs #{qualified_name}: #{type}\n"
31
29
  end
32
30
  true
@@ -9,18 +9,16 @@ module RubyModKit
9
9
  # The mission for parameter types
10
10
  class TypeReturnMission < Mission
11
11
  # @rbs generation: Generation
12
- # @rbs root_node: Node::ProgramNode
13
- # @rbs parse_result: Prism::ParseResult
14
- # @rbs memo_pad: MemoPad
15
12
  # @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)
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)
19
16
  raise RubyModKit::Error, "DefNode not found" if !def_node || !def_node.is_a?(Node::DefNode)
20
17
  next if method_memo.untyped?
21
18
 
22
- src_offset = parse_result.source.offsets[def_node.location.start_line - 1]
19
+ src_offset = generation.offsets[def_node.location.start_line - 1]
23
20
  indent = offset - src_offset
21
+ generation.memo_pad.flags[:rbs_annotated] = true
24
22
  generation[src_offset, 0] = "#{" " * indent}# @rbs return: #{method_memo.type}\n"
25
23
  end
26
24
  true
@@ -15,6 +15,8 @@ module RubyModKit
15
15
  TypeOverloadMission.new,
16
16
  TypeParameterMission.new,
17
17
  TypeReturnMission.new,
18
+ # This mission must be the last
19
+ AddMagicCommentMission.new,
18
20
  ]
19
21
  end
20
22
  end
@@ -22,6 +24,7 @@ module RubyModKit
22
24
  end
23
25
  end
24
26
 
27
+ require_relative "rbs_inline/add_magic_comment_mission"
25
28
  require_relative "rbs_inline/type_attr_mission"
26
29
  require_relative "rbs_inline/type_instance_variable_mission"
27
30
  require_relative "rbs_inline/type_overload_mission"
@@ -14,13 +14,11 @@ module RubyModKit
14
14
 
15
15
  # @rbs parse_error: Prism::ParseError
16
16
  # @rbs generation: Generation
17
- # @rbs root_node: Node::ProgramNode
18
- # @rbs memo_pad: MemoPad
19
17
  # @rbs return: void
20
- def correct(parse_error, generation, root_node, memo_pad)
18
+ def correct(parse_error, generation)
21
19
  return if parse_error.location.slice != ":"
22
20
 
23
- def_node = root_node.statements_node_at(parse_error.location.start_offset)&.parent
21
+ def_node = generation.root_node.statements_node_at(parse_error.location.start_offset)&.parent
24
22
  return unless def_node.is_a?(Node::DefNode)
25
23
 
26
24
  lparen_loc = def_node.lparen_loc
@@ -34,10 +32,10 @@ module RubyModKit
34
32
  end
35
33
  return if generation[src_offset...parse_error.location.start_offset] !~ /\A\s*\z/
36
34
 
37
- right_node = root_node.node_at(parse_error.location.end_offset + 1)
35
+ right_node = generation.root_node.node_at(parse_error.location.end_offset + 1)
38
36
  return_type_location = right_node&.location || return_type_location
39
37
  generation[src_offset, return_type_location.end_offset - src_offset] = ""
40
- memo_pad.method_memo(def_node).type = return_type_location.slice
38
+ generation.memo_pad.method_memo(def_node).type = return_type_location.slice
41
39
  end
42
40
  end
43
41
  end