ruby_mod_kit 0.0.3 → 0.0.4

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