ruby_mod_kit 0.0.1 → 0.0.3
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.
- checksums.yaml +4 -4
- data/README.md +14 -8
- data/lib/ruby_mod_kit/cli.rb +10 -1
- data/lib/ruby_mod_kit/core_ext/eval.rb +36 -0
- data/lib/ruby_mod_kit/core_ext/load.rb +74 -0
- data/lib/ruby_mod_kit/core_ext.rb +7 -0
- data/lib/ruby_mod_kit/corrector.rb +22 -0
- data/lib/ruby_mod_kit/corrector_manager.rb +68 -0
- data/lib/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_corrector.rb +42 -0
- data/lib/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_mission.rb +49 -0
- data/lib/ruby_mod_kit/feature/instance_variable_parameter.rb +27 -0
- data/lib/ruby_mod_kit/feature/overload/overload_mission.rb +80 -0
- data/lib/ruby_mod_kit/feature/overload.rb +19 -0
- data/lib/ruby_mod_kit/feature/type/instance_variable_colon_corrector.rb +49 -0
- data/lib/ruby_mod_kit/feature/type/parameter_arrow_corrector.rb +90 -0
- data/lib/ruby_mod_kit/feature/type/rbs_inline/type_attr_mission.rb +41 -0
- data/lib/ruby_mod_kit/feature/type/rbs_inline/type_instance_variable_mission.rb +31 -0
- data/lib/ruby_mod_kit/feature/type/rbs_inline/type_overload_mission.rb +43 -0
- data/lib/ruby_mod_kit/feature/type/rbs_inline/type_parameter_mission.rb +38 -0
- data/lib/ruby_mod_kit/feature/type/rbs_inline/type_return_mission.rb +32 -0
- data/lib/ruby_mod_kit/feature/type/rbs_inline.rb +29 -0
- data/lib/ruby_mod_kit/feature/type/return_value_colon_corrector.rb +45 -0
- data/lib/ruby_mod_kit/feature/type/type_attr_mission.rb +67 -0
- data/lib/ruby_mod_kit/feature/type.rb +31 -0
- data/lib/ruby_mod_kit/feature.rb +24 -0
- data/lib/ruby_mod_kit/generation.rb +60 -22
- data/lib/ruby_mod_kit/memo/def_parent_memo.rb +36 -0
- data/lib/ruby_mod_kit/memo/{ivar.rb → ivar_memo.rb} +17 -3
- data/lib/ruby_mod_kit/memo/{method.rb → method_memo.rb} +7 -7
- data/lib/ruby_mod_kit/memo/offset_memo.rb +1 -1
- data/lib/ruby_mod_kit/memo/overload_memo.rb +46 -0
- data/lib/ruby_mod_kit/memo/{parameter.rb → parameter_memo.rb} +3 -3
- data/lib/ruby_mod_kit/memo.rb +7 -64
- data/lib/ruby_mod_kit/memo_pad.rb +69 -0
- data/lib/ruby_mod_kit/mission.rb +5 -24
- data/lib/ruby_mod_kit/node/base_node.rb +137 -0
- data/lib/ruby_mod_kit/node/call_node.rb +10 -6
- data/lib/ruby_mod_kit/node/def_node.rb +10 -6
- data/lib/ruby_mod_kit/node/def_parent_node.rb +41 -0
- data/lib/ruby_mod_kit/node/parameter_node.rb +12 -8
- data/lib/ruby_mod_kit/node/program_node.rb +2 -2
- data/lib/ruby_mod_kit/node/statements_node.rb +10 -6
- data/lib/ruby_mod_kit/node/symbol_node.rb +10 -6
- data/lib/ruby_mod_kit/node/untyped_node.rb +10 -6
- data/lib/ruby_mod_kit/node/wrap.rb +43 -0
- data/lib/ruby_mod_kit/node.rb +5 -149
- data/lib/ruby_mod_kit/offset_diff.rb +12 -6
- data/lib/ruby_mod_kit/version.rb +1 -1
- data/lib/ruby_mod_kit.rb +43 -11
- data/ruby_mod_kit.gemspec +1 -6
- data/sig/generated/ruby_mod_kit/core_ext/eval.rbs +17 -0
- data/sig/generated/ruby_mod_kit/core_ext/load.rbs +33 -0
- data/sig/generated/ruby_mod_kit/corrector.rbs +16 -0
- data/sig/generated/ruby_mod_kit/corrector_manager.rbs +26 -0
- data/sig/generated/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_corrector.rbs +20 -0
- data/sig/generated/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_mission.rbs +21 -0
- data/sig/generated/ruby_mod_kit/feature/instance_variable_parameter.rbs +14 -0
- data/sig/generated/ruby_mod_kit/feature/overload/overload_mission.rbs +24 -0
- data/sig/generated/ruby_mod_kit/feature/overload.rbs +11 -0
- data/sig/generated/ruby_mod_kit/feature/type/instance_variable_colon_corrector.rbs +20 -0
- data/sig/generated/ruby_mod_kit/feature/type/parameter_arrow_corrector.rbs +39 -0
- data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_attr_mission.rbs +19 -0
- data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_instance_variable_mission.rbs +19 -0
- data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_overload_mission.rbs +19 -0
- data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_parameter_mission.rbs +19 -0
- data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_return_mission.rbs +19 -0
- data/sig/generated/ruby_mod_kit/feature/type/rbs_inline.rbs +13 -0
- data/sig/generated/ruby_mod_kit/feature/type/return_value_colon_corrector.rbs +20 -0
- data/sig/generated/ruby_mod_kit/feature/type/type_attr_mission.rbs +20 -0
- data/sig/generated/ruby_mod_kit/feature/type.rbs +14 -0
- data/sig/generated/ruby_mod_kit/feature.rbs +16 -0
- data/sig/generated/ruby_mod_kit/generation.rbs +25 -10
- data/sig/generated/ruby_mod_kit/memo/def_parent_memo.rbs +24 -0
- data/sig/generated/ruby_mod_kit/memo/{ivar.rbs → ivar_memo.rbs} +15 -3
- data/sig/generated/ruby_mod_kit/memo/{method.rbs → method_memo.rbs} +8 -8
- data/sig/generated/ruby_mod_kit/memo/offset_memo.rbs +1 -1
- data/sig/generated/ruby_mod_kit/memo/overload_memo.rbs +32 -0
- data/sig/generated/ruby_mod_kit/memo/{parameter.rbs → parameter_memo.rbs} +3 -3
- data/sig/generated/ruby_mod_kit/memo.rbs +2 -36
- data/sig/generated/ruby_mod_kit/memo_pad.rbs +46 -0
- data/sig/generated/ruby_mod_kit/mission.rbs +4 -12
- data/sig/generated/ruby_mod_kit/node/base_node.rbs +65 -0
- data/sig/generated/ruby_mod_kit/node/call_node.rbs +11 -6
- data/sig/generated/ruby_mod_kit/node/def_node.rbs +11 -6
- data/sig/generated/ruby_mod_kit/node/def_parent_node.rbs +31 -0
- data/sig/generated/ruby_mod_kit/node/parameter_node.rbs +13 -8
- data/sig/generated/ruby_mod_kit/node/program_node.rbs +2 -2
- data/sig/generated/ruby_mod_kit/node/statements_node.rbs +11 -6
- data/sig/generated/ruby_mod_kit/node/symbol_node.rbs +11 -6
- data/sig/generated/ruby_mod_kit/node/untyped_node.rbs +11 -6
- data/sig/generated/ruby_mod_kit/node/wrap.rbs +12 -0
- data/sig/generated/ruby_mod_kit/node.rbs +2 -58
- data/sig/generated/ruby_mod_kit/offset_diff.rbs +3 -1
- data/sig/generated/ruby_mod_kit.rbs +13 -2
- data/sig/thor.rbs +2 -0
- metadata +63 -43
- data/lib/ruby_mod_kit/memo/class.rb +0 -27
- data/lib/ruby_mod_kit/mission/fix_parse_error.rb +0 -213
- data/lib/ruby_mod_kit/mission/ivar_arg.rb +0 -42
- data/lib/ruby_mod_kit/mission/overload.rb +0 -73
- data/lib/ruby_mod_kit/mission/type_attr.rb +0 -75
- data/lib/ruby_mod_kit/mission/type_parameter.rb +0 -39
- data/lib/ruby_mod_kit/mission/type_return.rb +0 -33
- data/lib/ruby_mod_kit/node/class_node.rb +0 -37
- data/lib/ruby_mod_kit/transpiler.rb +0 -20
- data/sig/generated/examples/user.rbs +0 -60
- data/sig/generated/ruby_mod_kit/memo/class.rbs +0 -20
- data/sig/generated/ruby_mod_kit/memo/located.rbs +0 -14
- data/sig/generated/ruby_mod_kit/memo/parameter_type.rbs +0 -14
- data/sig/generated/ruby_mod_kit/mission/fix_parse_error.rbs +0 -73
- data/sig/generated/ruby_mod_kit/mission/ivar_arg.rbs +0 -19
- data/sig/generated/ruby_mod_kit/mission/overload.rbs +0 -20
- data/sig/generated/ruby_mod_kit/mission/type_attr.rbs +0 -18
- data/sig/generated/ruby_mod_kit/mission/type_parameter.rbs +0 -18
- data/sig/generated/ruby_mod_kit/mission/type_return.rbs +0 -18
- data/sig/generated/ruby_mod_kit/node/class_node.rbs +0 -29
- data/sig/generated/ruby_mod_kit/transpiler.rbs +0 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 36509ee4c00db1106b7447ba1d4fe09ee2fd2a8f8ce763c40b1da185f19cfc61
|
|
4
|
+
data.tar.gz: eccbdb68bb6159aa95c7fda5d171e4089b9dfa9b262ef136caf019fa3c339d7f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a8b12f06259193345becd29a14a1c6397481c41b390daed390cf4ed0bc7016afe0fbcf9ba95a9c3639b37150c98791d3e501cf2490725bfc5cf3c405fdc99f94
|
|
7
|
+
data.tar.gz: 684d9b858ac50e78b40f92a2d1cb8ddaafb99983bbdafc7788d786878af5b03c2187995bbe312de59495c9e4f796c352a9e203428d91018075a88791a79320eb
|
data/README.md
CHANGED
|
@@ -20,20 +20,26 @@ If bundler is not being used to manage dependencies, install the gem by executin
|
|
|
20
20
|
#### `transpile`
|
|
21
21
|
|
|
22
22
|
You can get transpiled ruby script from .rbm file by `ruby_mod_kit transpile` command.
|
|
23
|
+
`transpile` command outputs script to stdout by default. `--output` can change output target.
|
|
24
|
+
`--output=.rb` is a special pattern that means "Output the original script file name with the extension changed to .rb".
|
|
23
25
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
These below have the same meaning: "Output ruby script to stdout".
|
|
27
|
+
|
|
28
|
+
$ ruby_mod_kit transpile path/to/script.rbm
|
|
29
|
+
$ ruby_mod_kit transpile --output=- path/to/script.rbm
|
|
30
|
+
$ ruby_mod_kit transpile --output=/dev/stdout path/to/script.rbm
|
|
31
|
+
|
|
32
|
+
These below have the same meaning: "Output ruby script to `path/to/script.rb`".
|
|
33
|
+
|
|
34
|
+
$ ruby_mod_kit transpile path/to/script.rbm > path/to/script.rb
|
|
35
|
+
$ ruby_mod_kit transpile --output=path/to/script.rb path/to/script.rbm
|
|
36
|
+
$ ruby_mod_kit transpile --output=.rb path/to/script.rbm
|
|
27
37
|
|
|
28
38
|
#### `exec`
|
|
29
39
|
|
|
30
40
|
You can run transpiled ruby script by `ruby_mod_kit exec` command.
|
|
31
41
|
|
|
32
|
-
|
|
33
|
-
ruby_mod_kit transpile path/to/script.rbm
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
The command also creates/updates ruby script before running.
|
|
42
|
+
$ ruby_mod_kit exec path/to/script.rbm
|
|
37
43
|
|
|
38
44
|
## Feature
|
|
39
45
|
|
data/lib/ruby_mod_kit/cli.rb
CHANGED
|
@@ -16,11 +16,20 @@ module RubyModKit
|
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
desc "transpile", "transpile rbm files"
|
|
19
|
+
method_option :output, type: :string
|
|
19
20
|
# @rbs *args: String
|
|
20
21
|
# @rbs return: void
|
|
21
22
|
def transpile(*args)
|
|
23
|
+
output = case options[:output]
|
|
24
|
+
when nil, "-", "/dev/stdout"
|
|
25
|
+
$stdout
|
|
26
|
+
when ".rb"
|
|
27
|
+
nil
|
|
28
|
+
else
|
|
29
|
+
options[:output]
|
|
30
|
+
end
|
|
22
31
|
args.each do |path|
|
|
23
|
-
RubyModKit.transpile_file(path)
|
|
32
|
+
RubyModKit.transpile_file(path, output: output || RubyModKit.rb_path(path))
|
|
24
33
|
end
|
|
25
34
|
end
|
|
26
35
|
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
require "ruby_mod_kit"
|
|
6
|
+
|
|
7
|
+
# Define RubyMotKit.eval
|
|
8
|
+
module RubyModKit
|
|
9
|
+
module CoreExt
|
|
10
|
+
# the extension for eval
|
|
11
|
+
module Eval
|
|
12
|
+
module_function
|
|
13
|
+
|
|
14
|
+
# @rbs expr: String
|
|
15
|
+
# @rbs *rest: Object
|
|
16
|
+
# @rbs transpile: bool
|
|
17
|
+
# @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
|
|
23
|
+
|
|
24
|
+
case rest
|
|
25
|
+
in [] | [Binding] | [Binding, String] | [Binding, String, Integer]
|
|
26
|
+
super(expr, *rest)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class << self
|
|
33
|
+
include(CoreExt::Eval)
|
|
34
|
+
public :eval
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
require "ruby_mod_kit"
|
|
6
|
+
require_relative "eval"
|
|
7
|
+
|
|
8
|
+
# Define RubyMotKit.load/require
|
|
9
|
+
module RubyModKit
|
|
10
|
+
module CoreExt
|
|
11
|
+
# the extension for load/require
|
|
12
|
+
module Load
|
|
13
|
+
LOADABLE_EXTS = %w[.rb .rbm .so .o .dll].freeze #: Array[String]
|
|
14
|
+
|
|
15
|
+
module_function
|
|
16
|
+
|
|
17
|
+
# @rbs path: String
|
|
18
|
+
# @rbs wrap: bool
|
|
19
|
+
# @rbs return: bool
|
|
20
|
+
def load(path, wrap = false) # rubocop:disable Style/OptionalBooleanParameter
|
|
21
|
+
return super unless path.end_with?(".rbm")
|
|
22
|
+
|
|
23
|
+
b = wrap ? binding : TOPLEVEL_BINDING
|
|
24
|
+
RubyModKit::CoreExt::Eval.eval(File.read(path), b, path)
|
|
25
|
+
true
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# @rbs path: String
|
|
29
|
+
# @rbs return: bool
|
|
30
|
+
def require(path)
|
|
31
|
+
require_path = Load.require_path(path)
|
|
32
|
+
return super unless require_path&.end_with?(".rbm")
|
|
33
|
+
return false if Load.loaded_features.include?(require_path)
|
|
34
|
+
|
|
35
|
+
Load.loaded_features << require_path
|
|
36
|
+
load(require_path)
|
|
37
|
+
true
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
class << self
|
|
41
|
+
# @rbs return: Array[String]
|
|
42
|
+
def loaded_features
|
|
43
|
+
$LOADED_FEATURES
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# @rbs return: Array[String]
|
|
47
|
+
def load_path
|
|
48
|
+
$LOAD_PATH
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# @rbs path: String
|
|
52
|
+
# @rbs expanded: bool
|
|
53
|
+
# @rbs return: String | nil
|
|
54
|
+
def require_path(path, expanded: false)
|
|
55
|
+
if !expanded && !File.absolute_path?(path)
|
|
56
|
+
return load_path.each.lazy.map { require_path(File.join(_1, path), expanded: true) }.find(&:itself)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
pathes = if path.end_with?(*LOADABLE_EXTS)
|
|
60
|
+
[path]
|
|
61
|
+
else
|
|
62
|
+
LOADABLE_EXTS.map { "#{path}#{_1}" }
|
|
63
|
+
end
|
|
64
|
+
pathes.find { File.exist?(_1) }
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
class << self
|
|
71
|
+
include(CoreExt::Load)
|
|
72
|
+
public :load, :require, :require_relative
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
module RubyModKit
|
|
6
|
+
# the base class of corrector
|
|
7
|
+
class Corrector
|
|
8
|
+
# @rbs return: Array[Symbol]
|
|
9
|
+
def correctable_error_types
|
|
10
|
+
[]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# @rbs _parse_error: Prism::ParseError
|
|
14
|
+
# @rbs _generation: Generation
|
|
15
|
+
# @rbs _root_node: Node::ProgramNode
|
|
16
|
+
# @rbs _memo_pad: MemoPad
|
|
17
|
+
# @rbs return: void
|
|
18
|
+
def correct(_parse_error, _generation, _root_node, _memo_pad)
|
|
19
|
+
raise RubyModKit::Error, "Unexpected type #{self.class}"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
module RubyModKit
|
|
6
|
+
# the class to manege parse error correctors
|
|
7
|
+
class CorrectorManager
|
|
8
|
+
# @rbs @previous_error_messages: Array[String]
|
|
9
|
+
# @rbs @correctors_error_map: Hash[Symbol, Array[Corrector]]
|
|
10
|
+
|
|
11
|
+
# @rbs features: Array[Feature]
|
|
12
|
+
# @rbs return: void
|
|
13
|
+
def initialize(features)
|
|
14
|
+
@previous_error_messages = []
|
|
15
|
+
@correctors_error_map = {}
|
|
16
|
+
features.each do |feature|
|
|
17
|
+
feature.create_correctors.each do |corrector|
|
|
18
|
+
corrector.correctable_error_types.each do |error_type|
|
|
19
|
+
(@correctors_error_map[error_type] ||= []) << corrector
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# @rbs generation: Generation
|
|
26
|
+
# @rbs root_node: Node::ProgramNode
|
|
27
|
+
# @rbs parse_result: Prism::ParseResult
|
|
28
|
+
# @rbs memo_pad: MemoPad
|
|
29
|
+
# @rbs return: bool
|
|
30
|
+
def perform(generation, root_node, parse_result, memo_pad)
|
|
31
|
+
return true if parse_result.errors.empty?
|
|
32
|
+
|
|
33
|
+
check_prev_errors(generation, parse_result)
|
|
34
|
+
@previous_error_messages = parse_result.errors.map(&:message)
|
|
35
|
+
|
|
36
|
+
parse_result.errors.each do |parse_error|
|
|
37
|
+
correctors = @correctors_error_map[parse_error.type] || next
|
|
38
|
+
correctors.each do |corrector|
|
|
39
|
+
corrector.correct(parse_error, generation, root_node, memo_pad)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
false
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# @rbs generation: Generation
|
|
47
|
+
# @rbs parse_result: Prism::ParseResult
|
|
48
|
+
# @rbs return: void
|
|
49
|
+
def check_prev_errors(generation, parse_result)
|
|
50
|
+
return if @previous_error_messages.empty?
|
|
51
|
+
return if parse_result.errors.empty?
|
|
52
|
+
return if @previous_error_messages != parse_result.errors.map(&:message)
|
|
53
|
+
|
|
54
|
+
message = +""
|
|
55
|
+
parse_result.errors.each do |parse_error|
|
|
56
|
+
message << "\n" unless message.empty?
|
|
57
|
+
message << "#{generation.name}:#{parse_error.location.start_line}:#{parse_error.message} "
|
|
58
|
+
message << "(#{parse_error.type})"
|
|
59
|
+
line = parse_result.source.lines[parse_error.location.start_line - 1]
|
|
60
|
+
if line
|
|
61
|
+
message << "\n#{line.chomp}\n"
|
|
62
|
+
message << "#{" " * parse_error.location.start_column}^#{"~" * [parse_error.location.length - 1, 0].max}"
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
raise RubyModKit::SyntaxError, message
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
data/lib/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_corrector.rb
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
module RubyModKit
|
|
6
|
+
class Feature
|
|
7
|
+
class InstanceVariableParameter
|
|
8
|
+
# the class to correct `def foo(@bar) ...` -> `def foo(bar) ...`
|
|
9
|
+
class InstanceVariableParameterCorrector < Corrector
|
|
10
|
+
# @rbs return: Array[Symbol]
|
|
11
|
+
def correctable_error_types
|
|
12
|
+
%i[argument_formal_ivar]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# @rbs parse_error: Prism::ParseError
|
|
16
|
+
# @rbs generation: Generation
|
|
17
|
+
# @rbs root_node: Node::ProgramNode
|
|
18
|
+
# @rbs memo_pad: MemoPad
|
|
19
|
+
# @rbs return: void
|
|
20
|
+
def correct(parse_error, generation, root_node, memo_pad)
|
|
21
|
+
src_offset = parse_error.location.start_offset
|
|
22
|
+
|
|
23
|
+
name = parse_error.location.slice[1..]
|
|
24
|
+
raise RubyModKit::Error unless name
|
|
25
|
+
|
|
26
|
+
parameter_position_node = root_node.node_at(src_offset)
|
|
27
|
+
raise RubyModKit::Error unless parameter_position_node
|
|
28
|
+
|
|
29
|
+
generation[src_offset, parse_error.location.length] = name
|
|
30
|
+
parameter_memo = memo_pad.parameter_memo(parameter_position_node)
|
|
31
|
+
parameter_memo.ivar_parameter = true
|
|
32
|
+
|
|
33
|
+
return unless parameter_memo.untyped?
|
|
34
|
+
|
|
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
|
|
37
|
+
parameter_memo.type = ivar_memo_type
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
data/lib/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_mission.rb
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
module RubyModKit
|
|
6
|
+
class Feature
|
|
7
|
+
class InstanceVariableParameter
|
|
8
|
+
# The mission for instance variable arguments
|
|
9
|
+
class InstanceVariableParameterMission < Mission
|
|
10
|
+
# @rbs @assignment: String
|
|
11
|
+
|
|
12
|
+
attr_reader :assignment #: String
|
|
13
|
+
|
|
14
|
+
# @rbs generation: Generation
|
|
15
|
+
# @rbs root_node: Node::ProgramNode
|
|
16
|
+
# @rbs _parse_result: Prism::ParseResult
|
|
17
|
+
# @rbs memo_pad: MemoPad
|
|
18
|
+
# @rbs return: bool
|
|
19
|
+
def perform(generation, root_node, _parse_result, memo_pad)
|
|
20
|
+
memo_pad.parameters_memo.each_value do |parameter_memo|
|
|
21
|
+
next unless parameter_memo.ivar_parameter
|
|
22
|
+
|
|
23
|
+
offset = parameter_memo.offset
|
|
24
|
+
parameter_node = root_node.parameter_node_at(offset)
|
|
25
|
+
raise RubyModKit::Error unless parameter_node
|
|
26
|
+
|
|
27
|
+
def_node = root_node.def_node_at(offset)
|
|
28
|
+
raise RubyModKit::Error, "DefNode not found" unless def_node
|
|
29
|
+
|
|
30
|
+
def_body_location = def_node.body_location
|
|
31
|
+
end_loc = def_node.end_keyword_loc
|
|
32
|
+
if def_body_location
|
|
33
|
+
indent = def_body_location.start_column
|
|
34
|
+
src_offset = def_body_location.start_offset - indent
|
|
35
|
+
elsif end_loc
|
|
36
|
+
indent = end_loc.start_column + 2
|
|
37
|
+
src_offset = end_loc.start_offset - indent + 2
|
|
38
|
+
end
|
|
39
|
+
raise RubyModKit::Error if !src_offset || !indent
|
|
40
|
+
|
|
41
|
+
name = parameter_node.name
|
|
42
|
+
generation[src_offset, 0] = "#{" " * indent}@#{name} = #{name}\n"
|
|
43
|
+
end
|
|
44
|
+
true
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
module RubyModKit
|
|
6
|
+
class Feature
|
|
7
|
+
# namespace for instance_variable parameter feature
|
|
8
|
+
class InstanceVariableParameter < Feature
|
|
9
|
+
# @rbs return: Array[Corrector]
|
|
10
|
+
def create_correctors
|
|
11
|
+
[
|
|
12
|
+
InstanceVariableParameterCorrector.new,
|
|
13
|
+
]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# @rbs return: Array[Mission]
|
|
17
|
+
def create_missions
|
|
18
|
+
[
|
|
19
|
+
InstanceVariableParameterMission.new,
|
|
20
|
+
]
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
require_relative "instance_variable_parameter/instance_variable_parameter_corrector"
|
|
27
|
+
require_relative "instance_variable_parameter/instance_variable_parameter_mission"
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
module RubyModKit
|
|
6
|
+
class Feature
|
|
7
|
+
class Overload
|
|
8
|
+
# The mission for overload
|
|
9
|
+
class OverloadMission < Mission
|
|
10
|
+
# @rbs @modified: bool
|
|
11
|
+
|
|
12
|
+
OVERLOAD_METHOD_MAP = {
|
|
13
|
+
"*": "_mul",
|
|
14
|
+
}.freeze #: Hash[Symbol, String]
|
|
15
|
+
|
|
16
|
+
# @rbs return: void
|
|
17
|
+
def initialize
|
|
18
|
+
super
|
|
19
|
+
@modified = false
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @rbs generation: Generation
|
|
23
|
+
# @rbs root_node: Node::ProgramNode
|
|
24
|
+
# @rbs parse_result: Prism::ParseResult
|
|
25
|
+
# @rbs memo_pad: MemoPad
|
|
26
|
+
# @rbs return: bool
|
|
27
|
+
def perform(generation, root_node, parse_result, memo_pad)
|
|
28
|
+
return true if @modified
|
|
29
|
+
|
|
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]
|
|
32
|
+
end
|
|
33
|
+
method_memo_groups.each_value do |method_memos|
|
|
34
|
+
next if method_memos.length <= 1
|
|
35
|
+
|
|
36
|
+
@modified = true
|
|
37
|
+
first_method_memo = method_memos.first
|
|
38
|
+
name = first_method_memo.name
|
|
39
|
+
first_def_node = root_node.def_node_at(first_method_memo.offset)
|
|
40
|
+
raise RubyModKit::Error unless first_def_node.is_a?(Node::DefNode)
|
|
41
|
+
raise RubyModKit::Error unless name.is_a?(Symbol)
|
|
42
|
+
|
|
43
|
+
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]
|
|
46
|
+
script = +""
|
|
47
|
+
|
|
48
|
+
overload_memo = memo_pad.overload_memo(first_method_memo.offset, name)
|
|
49
|
+
|
|
50
|
+
method_memos.each do |method_memo|
|
|
51
|
+
type = method_memo.type
|
|
52
|
+
type = "(#{type})" if type.include?(" ")
|
|
53
|
+
overload_memo.add_overload_type(method_memo.parameters.map(&:type), type)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
script << "def #{name}(*args)\n case args\n"
|
|
57
|
+
overload_prefix = +"#{OVERLOAD_METHOD_MAP[name] || name}_"
|
|
58
|
+
method_memos.each_with_index do |method_memo, i|
|
|
59
|
+
overload_name = "#{overload_prefix}_overload#{i}"
|
|
60
|
+
def_node = root_node.def_node_at(method_memo.offset)
|
|
61
|
+
raise RubyModKit::Error if !def_node || !def_node.is_a?(Node::DefNode)
|
|
62
|
+
|
|
63
|
+
name_loc = def_node.name_loc
|
|
64
|
+
generation[name_loc.start_offset, name_loc.length] = overload_name
|
|
65
|
+
script << " in [#{method_memo.parameters.map(&:type).join(", ")}]\n"
|
|
66
|
+
script << " #{overload_name}(*args)\n"
|
|
67
|
+
end
|
|
68
|
+
script << " end\nend\n\n"
|
|
69
|
+
|
|
70
|
+
script.gsub!(/^(?=.)/, indent)
|
|
71
|
+
generation[src_offset, 0] = script
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# if script has been changed, request reparsing before proceeding to the next mission
|
|
75
|
+
!@modified
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
module RubyModKit
|
|
6
|
+
class Feature
|
|
7
|
+
# namespace for overload feature
|
|
8
|
+
class Overload < Feature
|
|
9
|
+
# @rbs return: Array[Mission]
|
|
10
|
+
def create_missions
|
|
11
|
+
[
|
|
12
|
+
OverloadMission.new,
|
|
13
|
+
]
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
require_relative "overload/overload_mission"
|
|
@@ -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
|
+
# the class to correct `@var: Type` -> `# @rbs @var: Type`
|
|
9
|
+
class InstanceVariableColonCorrector < Corrector
|
|
10
|
+
# @rbs return: Array[Symbol]
|
|
11
|
+
def correctable_error_types
|
|
12
|
+
%i[unexpected_token_ignore]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# @rbs parse_error: Prism::ParseError
|
|
16
|
+
# @rbs generation: Generation
|
|
17
|
+
# @rbs root_node: Node::ProgramNode
|
|
18
|
+
# @rbs memo_pad: MemoPad
|
|
19
|
+
# @rbs return: void
|
|
20
|
+
def correct(parse_error, generation, root_node, memo_pad)
|
|
21
|
+
return if parse_error.location.slice != ":"
|
|
22
|
+
|
|
23
|
+
def_parent_node = root_node.statements_node_at(parse_error.location.start_offset)&.parent
|
|
24
|
+
return unless def_parent_node.is_a?(Node::DefParentNode)
|
|
25
|
+
|
|
26
|
+
line = generation.line(parse_error)
|
|
27
|
+
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
|
+
|
|
31
|
+
length = ::Regexp.last_match(0)&.length
|
|
32
|
+
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)
|
|
36
|
+
return if !length || !indent || !ivar_name || !type
|
|
37
|
+
|
|
38
|
+
ivar_memo = memo_pad.def_parent_memo(def_parent_node).ivar_memo(ivar_name.to_sym)
|
|
39
|
+
ivar_memo.type = type
|
|
40
|
+
ivar_memo.offset = line_offset
|
|
41
|
+
ivar_memo.indent = indent
|
|
42
|
+
ivar_memo.attr_kind = attr_kind if attr_kind
|
|
43
|
+
|
|
44
|
+
generation[line_offset, length] = ""
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
module RubyModKit
|
|
6
|
+
class Feature
|
|
7
|
+
class Type
|
|
8
|
+
# the class to correct `def foo(Bar => bar, *Buz => buz)` -> `def foo(bar, *buz)`
|
|
9
|
+
class ParameterArrowCorrector < Corrector
|
|
10
|
+
# @rbs return: Array[Symbol]
|
|
11
|
+
def correctable_error_types
|
|
12
|
+
%i[unexpected_token_ignore def_params_term_paren argument_formal_constant]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# @rbs parse_error: Prism::ParseError
|
|
16
|
+
# @rbs generation: Generation
|
|
17
|
+
# @rbs root_node: Node::ProgramNode
|
|
18
|
+
# @rbs memo_pad: MemoPad
|
|
19
|
+
# @rbs return: void
|
|
20
|
+
def correct(parse_error, generation, root_node, memo_pad)
|
|
21
|
+
case parse_error.type
|
|
22
|
+
when :unexpected_token_ignore
|
|
23
|
+
return if parse_error.location.slice != "=>"
|
|
24
|
+
|
|
25
|
+
remove_arrow_before_parameter(parse_error, generation, root_node, memo_pad)
|
|
26
|
+
when :def_params_term_paren
|
|
27
|
+
remove_arrow_after_quailifier(parse_error, generation, root_node, memo_pad)
|
|
28
|
+
when :argument_formal_constant
|
|
29
|
+
wrap_parameter_type_for_next_parse(parse_error, generation)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# @rbs parse_error: Prism::ParseError
|
|
34
|
+
# @rbs generation: Generation
|
|
35
|
+
# @rbs root_node: Node::ProgramNode
|
|
36
|
+
# @rbs memo_pad: MemoPad
|
|
37
|
+
# @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
|
|
40
|
+
def_parent_node = def_node.parent
|
|
41
|
+
parameters_node, body_node, = def_node.children
|
|
42
|
+
return if !def_parent_node || !parameters_node || !body_node
|
|
43
|
+
|
|
44
|
+
last_parameter_node = parameters_node.children.max_by(&:offset) || return
|
|
45
|
+
last_parameter_offset = last_parameter_node.offset
|
|
46
|
+
|
|
47
|
+
right_node = body_node.children.find { _1.offset >= parse_error.location.end_offset } || return
|
|
48
|
+
right_offset = right_node.offset
|
|
49
|
+
parameter_type = generation[last_parameter_offset...right_offset] || raise(RubyModKit::Error)
|
|
50
|
+
parameter_type = parameter_type.sub(/\s*=>\s*\z/, "")
|
|
51
|
+
generation[last_parameter_offset, right_offset - last_parameter_offset] = ""
|
|
52
|
+
memo_pad.parameter_memo(last_parameter_node).type = parameter_type
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# @rbs parse_error: Prism::ParseError
|
|
56
|
+
# @rbs generation: Generation
|
|
57
|
+
# @rbs root_node: Node::ProgramNode
|
|
58
|
+
# @rbs memo_pad: MemoPad
|
|
59
|
+
# @rbs return: void
|
|
60
|
+
def remove_arrow_after_quailifier(parse_error, generation, root_node, memo_pad)
|
|
61
|
+
column = parse_error.location.start_column - 1
|
|
62
|
+
return if column < 0
|
|
63
|
+
|
|
64
|
+
line = generation.line(parse_error)[column..] || return
|
|
65
|
+
line =~ /\A\*(.*?)\s*=>\s*/
|
|
66
|
+
length = ::Regexp.last_match(0)&.length || return
|
|
67
|
+
type = ::Regexp.last_match(1) || return
|
|
68
|
+
offset = parse_error.location.start_offset - 1
|
|
69
|
+
parameter_position_node = root_node.node_at(offset + length) || return
|
|
70
|
+
|
|
71
|
+
generation[parse_error.location.start_offset, length - 1] = ""
|
|
72
|
+
parameter_memo = memo_pad.parameter_memo(parameter_position_node)
|
|
73
|
+
parameter_memo.type = type
|
|
74
|
+
parameter_memo.qualifier = "*"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# @rbs parse_error: Prism::ParseError
|
|
78
|
+
# @rbs generation: Generation
|
|
79
|
+
# @rbs return: void
|
|
80
|
+
def wrap_parameter_type_for_next_parse(parse_error, generation)
|
|
81
|
+
line = generation.line(parse_error)
|
|
82
|
+
line = line[parse_error.location.start_column..] || return
|
|
83
|
+
parameter_type = line[/(\A[A-Z]\w*(?:::[A-Z]\w*)+)(?:\s*=>\s*)/, 1] || return
|
|
84
|
+
src_offset = parse_error.location.start_offset
|
|
85
|
+
generation[src_offset, parameter_type.length] = "(#{parameter_type})"
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
module RubyModKit
|
|
6
|
+
class Feature
|
|
7
|
+
class Type
|
|
8
|
+
class RbsInline
|
|
9
|
+
# The mission for parameter types
|
|
10
|
+
class TypeAttrMission < Mission
|
|
11
|
+
# @rbs generation: Generation
|
|
12
|
+
# @rbs root_node: Node::ProgramNode
|
|
13
|
+
# @rbs _parse_result: Prism::ParseResult
|
|
14
|
+
# @rbs memo_pad: MemoPad
|
|
15
|
+
# @rbs return: bool
|
|
16
|
+
def perform(generation, root_node, _parse_result, memo_pad)
|
|
17
|
+
memo_pad.def_parents_memo.each_value do |def_parent_memo|
|
|
18
|
+
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)
|
|
20
|
+
def_parent_node.body_node&.children&.each do |call_node|
|
|
21
|
+
break if ivars_memo.empty?
|
|
22
|
+
next unless call_node.is_a?(Node::CallNode)
|
|
23
|
+
next unless %i[attr_reader attr_writer attr_accessor].include?(call_node.name)
|
|
24
|
+
|
|
25
|
+
argument_nodes = call_node.children[0].children
|
|
26
|
+
next if argument_nodes.size != 1 || !argument_nodes[0].is_a?(Node::SymbolNode)
|
|
27
|
+
|
|
28
|
+
name = argument_nodes[0].value || next
|
|
29
|
+
ivar_memo = ivars_memo.delete(name) || next
|
|
30
|
+
line = generation.line(call_node)
|
|
31
|
+
length = line[/\A\s*(#{call_node.name}\s+:#{name})(?=\n\z)/, 1]&.length || next
|
|
32
|
+
generation[call_node.location.start_offset + length, 0] = " #: #{ivar_memo.type}"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
true
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|