ruby_mod_kit 0.0.4 → 0.0.5
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 +89 -0
- data/lib/ruby_mod_kit/core_ext/eval.rb +6 -10
- data/lib/ruby_mod_kit/corrector.rb +3 -0
- data/lib/ruby_mod_kit/corrector_manager.rb +10 -6
- data/lib/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_mission.rb +1 -1
- data/lib/ruby_mod_kit/feature/overload/overload_mission.rb +2 -3
- data/lib/ruby_mod_kit/feature/type/check/arguments/add_arguments_checker_mission.rb +56 -0
- data/lib/ruby_mod_kit/feature/type/check/arguments.rb +23 -0
- data/lib/ruby_mod_kit/feature/type/instance_variable_colon_corrector.rb +9 -4
- data/lib/ruby_mod_kit/feature/type/parameter_arrow_corrector.rb +27 -5
- data/lib/ruby_mod_kit/feature/type/rbs_inline/type_instance_variable_mission.rb +3 -2
- data/lib/ruby_mod_kit/feature/type/rbs_inline/type_overload_mission.rb +1 -2
- data/lib/ruby_mod_kit/feature/type/rbs_inline/type_parameter_mission.rb +5 -4
- data/lib/ruby_mod_kit/feature/type/rbs_inline/type_return_mission.rb +1 -1
- data/lib/ruby_mod_kit/feature/type/return_value_colon_corrector.rb +1 -0
- data/lib/ruby_mod_kit/feature/type/type_attr_mission.rb +3 -9
- data/lib/ruby_mod_kit/feature/type/yard/type_parameter_mission.rb +35 -0
- data/lib/ruby_mod_kit/feature/type/yard/type_return_mission.rb +30 -0
- data/lib/ruby_mod_kit/feature/type/yard.rb +31 -0
- data/lib/ruby_mod_kit/generation.rb +55 -20
- data/lib/ruby_mod_kit/memo/ivar_memo.rb +2 -0
- data/lib/ruby_mod_kit/memo/parameter_memo.rb +4 -2
- data/lib/ruby_mod_kit/memo_pad.rb +6 -0
- data/lib/ruby_mod_kit/mission.rb +0 -4
- data/lib/ruby_mod_kit/node/base_node.rb +11 -2
- data/lib/ruby_mod_kit/node/begin_node.rb +31 -0
- data/lib/ruby_mod_kit/node/parameter_node.rb +2 -2
- data/lib/ruby_mod_kit/node/wrap.rb +3 -1
- data/lib/ruby_mod_kit/node.rb +1 -0
- data/lib/ruby_mod_kit/version.rb +1 -1
- data/lib/ruby_mod_kit.rb +0 -5
- data/sig/generated/ruby_mod_kit/core_ext/eval.rbs +4 -2
- data/sig/generated/ruby_mod_kit/corrector.rbs +3 -0
- data/sig/generated/ruby_mod_kit/corrector_manager.rbs +1 -1
- data/sig/generated/ruby_mod_kit/feature/type/check/arguments/add_arguments_checker_mission.rbs +16 -0
- data/sig/generated/ruby_mod_kit/feature/type/check/arguments.rbs +15 -0
- data/sig/generated/ruby_mod_kit/feature/type/parameter_arrow_corrector.rbs +5 -0
- data/sig/generated/ruby_mod_kit/feature/type/yard/type_parameter_mission.rbs +16 -0
- data/sig/generated/ruby_mod_kit/feature/type/yard/type_return_mission.rbs +16 -0
- data/sig/generated/ruby_mod_kit/feature/type/yard.rbs +17 -0
- data/sig/generated/ruby_mod_kit/generation.rbs +34 -10
- data/sig/generated/ruby_mod_kit/memo/ivar_memo.rbs +4 -0
- data/sig/generated/ruby_mod_kit/memo/parameter_memo.rbs +6 -2
- data/sig/generated/ruby_mod_kit/memo_pad.rbs +4 -0
- data/sig/generated/ruby_mod_kit/mission.rbs +0 -4
- data/sig/generated/ruby_mod_kit/node/base_node.rbs +5 -1
- data/sig/generated/ruby_mod_kit/node/begin_node.rbs +26 -0
- data/sig/generated/ruby_mod_kit/node/parameter_node.rbs +1 -1
- metadata +14 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e5888d6187dc2620b37315d72fddee6b134bbd14181277ff600e864eb9c06ca0
|
|
4
|
+
data.tar.gz: 7ffb4ec96c231e6122eeaa7d47601f67a28620951ed08e9d3b3888e9fa684fbc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3c2e632593d2d0a7061f8a71a7e65131a1b72434ac3853467024503d13c57328abe88ade105b2532baf94d44bd428bd02b4eae9e0c50462d4dca6bebc767d4f9
|
|
7
|
+
data.tar.gz: 81b17d66702c1fc89c77bc3270f74608fca6ed8e9a12f26c04ea69f7d0bdceb4b91b104bfa45b0f944e5ba5dae79e789de720b8a5605df0d4ac4bb4e48e62d6d
|
data/README.md
CHANGED
|
@@ -15,6 +15,95 @@ If bundler is not being used to manage dependencies, install the gem by executin
|
|
|
15
15
|
|
|
16
16
|
## Usage
|
|
17
17
|
|
|
18
|
+
### as library
|
|
19
|
+
|
|
20
|
+
`RubyModKit.transpile` returns transpiled script.
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
require "ruby_mod_kit"
|
|
24
|
+
eval(
|
|
25
|
+
RubyModKit.transpile(<<~RBM),
|
|
26
|
+
class Foo
|
|
27
|
+
getter @foo: Integer
|
|
28
|
+
def initialize(@foo)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
RBM
|
|
32
|
+
)
|
|
33
|
+
p Foo.new(1).foo # => 1
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
`require "ruby_mod_kit/core_ext/eval"` gives `RubyModKit.eval`.
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
require "ruby_mod_kit/core_ext/eval"
|
|
40
|
+
RubyModKit.eval(<<~RBM)
|
|
41
|
+
class Foo
|
|
42
|
+
getter @foo: Integer
|
|
43
|
+
def initialize(@foo)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
RBM
|
|
47
|
+
p Foo.new(1).foo # => 1
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
`require "ruby_mod_kit/core_ext/load"` gives `RubyModKit.load` and `RubyModKit.require`.
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
require "ruby_mod_kit/core_ext/load"
|
|
54
|
+
require "tmpdir"
|
|
55
|
+
|
|
56
|
+
script = <<~RBM
|
|
57
|
+
class Foo
|
|
58
|
+
getter @foo: Integer
|
|
59
|
+
def initialize(@foo)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
RBM
|
|
63
|
+
|
|
64
|
+
Dir.mktmpdir do |tmpdir|
|
|
65
|
+
File.write("#{tmpdir}/some_lib.rbm", script)
|
|
66
|
+
$LOAD_PATH << tmpdir
|
|
67
|
+
RubyModKit.require "some_lib"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
p Foo.new(1).foo # => 1
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
And `require "ruby_mod_kit/core_ext"` is more powerfull but dangerous. It overwrites `eval`, `require` and `load`.
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
require "ruby_mod_kit/core_ext"
|
|
77
|
+
eval(<<~RBM)
|
|
78
|
+
class Foo
|
|
79
|
+
getter @foo: Integer
|
|
80
|
+
def initialize(@foo)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
RBM
|
|
84
|
+
p Foo.new(1).foo # => 1
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
require "ruby_mod_kit/core_ext"
|
|
89
|
+
require "tmpdir"
|
|
90
|
+
|
|
91
|
+
script = <<~RBM
|
|
92
|
+
class Foo
|
|
93
|
+
getter @foo: Integer
|
|
94
|
+
def initialize(@foo)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
RBM
|
|
98
|
+
|
|
99
|
+
Dir.mktmpdir do |tmpdir|
|
|
100
|
+
File.write("#{tmpdir}/some_lib.rbm", script)
|
|
101
|
+
$LOAD_PATH << tmpdir
|
|
102
|
+
require "some_lib"
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
p Foo.new(1).foo # => 1
|
|
106
|
+
```
|
|
18
107
|
### as command line tool
|
|
19
108
|
|
|
20
109
|
#### `transpile`
|
|
@@ -12,19 +12,15 @@ module RubyModKit
|
|
|
12
12
|
module_function
|
|
13
13
|
|
|
14
14
|
# @rbs expr: String
|
|
15
|
-
# @rbs
|
|
15
|
+
# @rbs binding: Binding
|
|
16
|
+
# @rbs fname: String
|
|
17
|
+
# @rbs lineno: Integer
|
|
16
18
|
# @rbs transpile: bool
|
|
17
19
|
# @rbs return: Object
|
|
18
|
-
def eval(expr,
|
|
19
|
-
if transpile
|
|
20
|
-
fname = rest[1].is_a?(String) ? rest[1] : "(eval)"
|
|
21
|
-
expr = RubyModKit.transpile(expr, filename: fname)
|
|
22
|
-
end
|
|
20
|
+
def eval(expr, binding = TOPLEVEL_BINDING, fname = "(eval)", lineno = 1, transpile: true)
|
|
21
|
+
expr = RubyModKit.transpile(expr, filename: fname) if transpile
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
in [] | [Binding] | [Binding, String] | [Binding, String, Integer]
|
|
26
|
-
super(expr, *rest)
|
|
27
|
-
end
|
|
23
|
+
super(expr, binding, fname, lineno)
|
|
28
24
|
end
|
|
29
25
|
end
|
|
30
26
|
end
|
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
module RubyModKit
|
|
6
6
|
# the class to manege parse error correctors
|
|
7
7
|
class CorrectorManager
|
|
8
|
-
# @rbs @
|
|
8
|
+
# @rbs @previous_source: String
|
|
9
9
|
# @rbs @correctors_error_map: Hash[Symbol, Array[Corrector]]
|
|
10
10
|
|
|
11
11
|
# @rbs features: Array[Feature]
|
|
12
12
|
# @rbs return: void
|
|
13
13
|
def initialize(features)
|
|
14
|
-
@
|
|
14
|
+
@previous_source = +""
|
|
15
15
|
@correctors_error_map = {}
|
|
16
16
|
features.each do |feature|
|
|
17
17
|
feature.create_correctors.each do |corrector|
|
|
@@ -28,7 +28,11 @@ module RubyModKit
|
|
|
28
28
|
return true if generation.errors.empty?
|
|
29
29
|
|
|
30
30
|
check_prev_errors(generation)
|
|
31
|
-
@
|
|
31
|
+
@previous_source = generation.script.dup
|
|
32
|
+
|
|
33
|
+
@correctors_error_map.each_value do |correctors|
|
|
34
|
+
correctors.each(&:setup)
|
|
35
|
+
end
|
|
32
36
|
|
|
33
37
|
generation.errors.each do |parse_error|
|
|
34
38
|
correctors = @correctors_error_map[parse_error.type] || next
|
|
@@ -43,16 +47,16 @@ module RubyModKit
|
|
|
43
47
|
# @rbs generation: Generation
|
|
44
48
|
# @rbs return: void
|
|
45
49
|
def check_prev_errors(generation)
|
|
46
|
-
return if @
|
|
50
|
+
return if @previous_source.empty?
|
|
47
51
|
return if generation.errors.empty?
|
|
48
|
-
return if @
|
|
52
|
+
return if @previous_source != generation.script
|
|
49
53
|
|
|
50
54
|
message = +""
|
|
51
55
|
generation.errors.each do |parse_error|
|
|
52
56
|
message << "\n" unless message.empty?
|
|
53
57
|
message << "#{generation.name}:#{parse_error.location.start_line}:#{parse_error.message} "
|
|
54
58
|
message << "(#{parse_error.type})"
|
|
55
|
-
line = generation.
|
|
59
|
+
line = generation.line(parse_error)
|
|
56
60
|
if line
|
|
57
61
|
message << "\n#{line.chomp}\n"
|
|
58
62
|
message << "#{" " * parse_error.location.start_column}^#{"~" * [parse_error.location.length - 1, 0].max}"
|
data/lib/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_mission.rb
CHANGED
|
@@ -10,7 +10,7 @@ module RubyModKit
|
|
|
10
10
|
# @rbs generation: Generation
|
|
11
11
|
# @rbs return: bool
|
|
12
12
|
def perform(generation)
|
|
13
|
-
generation.memo_pad.
|
|
13
|
+
generation.memo_pad.each_parameter_memo do |parameter_memo|
|
|
14
14
|
next unless parameter_memo.ivar_parameter
|
|
15
15
|
|
|
16
16
|
offset = parameter_memo.offset
|
|
@@ -37,9 +37,8 @@ module RubyModKit
|
|
|
37
37
|
raise RubyModKit::Error unless first_def_node.is_a?(Node::DefNode)
|
|
38
38
|
raise RubyModKit::Error unless name.is_a?(Symbol)
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
src_offset = generation.offsets[start_line]
|
|
40
|
+
indent = generation.line_indent(first_def_node)
|
|
41
|
+
src_offset = generation.line_offset(first_def_node) || raise(RubyModKit::Error)
|
|
43
42
|
script = +""
|
|
44
43
|
|
|
45
44
|
overload_memo = generation.memo_pad.overload_memo(first_method_memo.offset, name)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
module RubyModKit
|
|
6
|
+
class Feature
|
|
7
|
+
class Type
|
|
8
|
+
module Check
|
|
9
|
+
# The mission to add magic comment
|
|
10
|
+
class AddArgumentsCheckerMission < Mission
|
|
11
|
+
# @rbs generation: Generation
|
|
12
|
+
# @rbs return: bool
|
|
13
|
+
def perform(generation)
|
|
14
|
+
# reload if line break is added
|
|
15
|
+
line_break_added = false
|
|
16
|
+
|
|
17
|
+
generation.memo_pad.methods_memo.each do |offset, method_memo|
|
|
18
|
+
def_node = generation.root_node.def_node_at(offset)
|
|
19
|
+
raise RubyModKit::Error, "DefNode not found" unless def_node
|
|
20
|
+
next if method_memo.parameters.empty?
|
|
21
|
+
|
|
22
|
+
def_line = generation.line(def_node.location.start_line - 1)
|
|
23
|
+
def_indent = def_line[/\A\s*/] || ""
|
|
24
|
+
|
|
25
|
+
location = def_node.body_location || def_node.end_keyword_loc
|
|
26
|
+
next unless location
|
|
27
|
+
|
|
28
|
+
def_right_loc = def_node.rparen_loc || def_node.name_loc
|
|
29
|
+
offset = location.start_offset - location.start_column
|
|
30
|
+
indent = "#{def_indent} "
|
|
31
|
+
if location.start_line == def_right_loc.end_line
|
|
32
|
+
between_def_and_loc = generation[def_right_loc.end_offset...location.start_offset]
|
|
33
|
+
length = between_def_and_loc[/\A[ ^t]*;[ ^t]*\z/]&.length
|
|
34
|
+
if length
|
|
35
|
+
line_break_added = true
|
|
36
|
+
generation[def_right_loc.end_offset, length] = "\n#{def_indent}"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
next if line_break_added
|
|
40
|
+
|
|
41
|
+
method_memo.parameters.each do |parameter_memo|
|
|
42
|
+
next if parameter_memo.untyped? || !parameter_memo.name
|
|
43
|
+
next if parameter_memo.qualifier # TODO: qualifier support
|
|
44
|
+
|
|
45
|
+
type = parameter_memo.type
|
|
46
|
+
type = type.gsub(/\[([^\[\]]+)\]/, "") # TODO: type variable support
|
|
47
|
+
generation[offset, 0] = "#{indent}#{parameter_memo.name} => #{type}\n"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
!line_break_added
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
module RubyModKit
|
|
6
|
+
class Feature
|
|
7
|
+
class Type
|
|
8
|
+
module Check
|
|
9
|
+
# namespace for arguments type checker
|
|
10
|
+
class Arguments < Feature
|
|
11
|
+
# @rbs return: Array[Mission]
|
|
12
|
+
def create_missions
|
|
13
|
+
[
|
|
14
|
+
AddArgumentsCheckerMission.new,
|
|
15
|
+
]
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
require_relative "arguments/add_arguments_checker_mission"
|
|
@@ -9,7 +9,7 @@ module RubyModKit
|
|
|
9
9
|
class InstanceVariableColonCorrector < Corrector
|
|
10
10
|
VISIBILITIES = %i[private public protected].freeze #: Array[Symbol]
|
|
11
11
|
ATTR_PATTERNS = %i[attr_reader reader getter attr_writer writer setter attr_accessor accessor property].freeze #: Array[Symbol]
|
|
12
|
-
REGEXP = /(\A\s*)(?:(#{VISIBILITIES.join("|")}) )?(?:(#{ATTR_PATTERNS.join("|")}) )?@(\w*)\s*:\s*(.*)\n
|
|
12
|
+
REGEXP = /(\A\s*)(?:(#{VISIBILITIES.join("|")}) )?(?:(#{ATTR_PATTERNS.join("|")}) )?@(\w*)\s*:\s*(.*)\n(\n+)?/.freeze #: Regexp
|
|
13
13
|
|
|
14
14
|
# @rbs return: Array[Symbol]
|
|
15
15
|
def correctable_error_types
|
|
@@ -22,11 +22,14 @@ module RubyModKit
|
|
|
22
22
|
def correct(parse_error, generation)
|
|
23
23
|
return if parse_error.location.slice != ":"
|
|
24
24
|
|
|
25
|
-
def_parent_node = generation.root_node.
|
|
25
|
+
def_parent_node = generation.root_node.def_parent_node_at(
|
|
26
|
+
parse_error.location.start_offset,
|
|
27
|
+
allowed: [Node::CallNode, Node::UntypedNode, Node::StatementsNode],
|
|
28
|
+
)
|
|
26
29
|
return unless def_parent_node.is_a?(Node::DefParentNode)
|
|
27
30
|
|
|
28
|
-
|
|
29
|
-
|
|
31
|
+
line_offset = generation.line_offset(parse_error) || return
|
|
32
|
+
line = generation[line_offset..]
|
|
30
33
|
return if line !~ REGEXP
|
|
31
34
|
|
|
32
35
|
length = ::Regexp.last_match(0)&.length
|
|
@@ -35,6 +38,7 @@ module RubyModKit
|
|
|
35
38
|
attr_kind = ::Regexp.last_match(3)
|
|
36
39
|
ivar_name = ::Regexp.last_match(4)
|
|
37
40
|
type = ::Regexp.last_match(5)
|
|
41
|
+
separator = ::Regexp.last_match(6)
|
|
38
42
|
return if !length || !indent || !ivar_name || !type
|
|
39
43
|
|
|
40
44
|
ivar_memo = generation.memo_pad.def_parent_memo(def_parent_node).ivar_memo(ivar_name.to_sym)
|
|
@@ -43,6 +47,7 @@ module RubyModKit
|
|
|
43
47
|
ivar_memo.indent = indent
|
|
44
48
|
ivar_memo.attr_kind = attr_kind if attr_kind
|
|
45
49
|
ivar_memo.visibility = visibility.to_sym if visibility
|
|
50
|
+
ivar_memo.separator = separator if separator
|
|
46
51
|
|
|
47
52
|
generation[line_offset, length] = ""
|
|
48
53
|
end
|
|
@@ -7,11 +7,19 @@ module RubyModKit
|
|
|
7
7
|
class Type
|
|
8
8
|
# the class to correct `def foo(Bar => bar, *Buz => buz)` -> `def foo(bar, *buz)`
|
|
9
9
|
class ParameterArrowCorrector < Corrector
|
|
10
|
+
# @rbs @last_parameter_offsets: Set[Integer]
|
|
11
|
+
|
|
10
12
|
# @rbs return: Array[Symbol]
|
|
11
13
|
def correctable_error_types
|
|
12
14
|
%i[unexpected_token_ignore def_params_term_paren argument_formal_constant]
|
|
13
15
|
end
|
|
14
16
|
|
|
17
|
+
# @rbs return: void
|
|
18
|
+
def setup
|
|
19
|
+
super
|
|
20
|
+
@last_parameter_offsets = Set.new
|
|
21
|
+
end
|
|
22
|
+
|
|
15
23
|
# @rbs parse_error: Prism::ParseError
|
|
16
24
|
# @rbs generation: Generation
|
|
17
25
|
# @rbs return: void
|
|
@@ -35,17 +43,29 @@ module RubyModKit
|
|
|
35
43
|
def_node = generation.root_node.def_node_at(parse_error.location.start_offset) || return
|
|
36
44
|
def_parent_node = def_node.parent
|
|
37
45
|
parameters_node, body_node, = def_node.children
|
|
46
|
+
body_node = body_node.children[0] if body_node.is_a?(Node::BeginNode)
|
|
38
47
|
return if !def_parent_node || !parameters_node || !body_node
|
|
39
48
|
|
|
40
49
|
last_parameter_node = parameters_node.children.max_by(&:offset) || return
|
|
41
50
|
last_parameter_offset = last_parameter_node.offset
|
|
51
|
+
return if @last_parameter_offsets.include?(last_parameter_offset)
|
|
42
52
|
|
|
53
|
+
@last_parameter_offsets << last_parameter_offset
|
|
43
54
|
right_node = body_node.children.find { _1.offset >= parse_error.location.end_offset } || return
|
|
44
55
|
right_offset = right_node.offset
|
|
56
|
+
name = right_node.slice[/\A\w+/]
|
|
45
57
|
parameter_type = generation[last_parameter_offset...right_offset] || raise(RubyModKit::Error)
|
|
46
58
|
parameter_type = parameter_type.sub(/\s*=>\s*\z/, "")
|
|
47
|
-
|
|
48
|
-
|
|
59
|
+
qualifier = nil
|
|
60
|
+
parameter_type = parameter_type.sub(/\A&\(\((.*)\) *: +(.*)\)\z/) do
|
|
61
|
+
qualifier = "&"
|
|
62
|
+
"(#{::Regexp.last_match(1)}) -> #{::Regexp.last_match(2)}"
|
|
63
|
+
end
|
|
64
|
+
generation[last_parameter_offset, right_offset - last_parameter_offset] = qualifier.to_s
|
|
65
|
+
parameter_memo = generation.memo_pad.parameter_memo(last_parameter_node)
|
|
66
|
+
parameter_memo.name = name.to_sym if name
|
|
67
|
+
parameter_memo.type = parameter_type
|
|
68
|
+
parameter_memo.qualifier = qualifier if qualifier
|
|
49
69
|
end
|
|
50
70
|
|
|
51
71
|
# @rbs parse_error: Prism::ParseError
|
|
@@ -56,15 +76,17 @@ module RubyModKit
|
|
|
56
76
|
return if column < 0
|
|
57
77
|
|
|
58
78
|
line = generation.line(parse_error)[column..] || return
|
|
59
|
-
line =~
|
|
60
|
-
length = ::Regexp.last_match(
|
|
61
|
-
type = ::Regexp.last_match(
|
|
79
|
+
line =~ /(\A\*(.*?)\s*=>\s*)(\w*)/
|
|
80
|
+
length = ::Regexp.last_match(1)&.length || return
|
|
81
|
+
type = ::Regexp.last_match(2) || return
|
|
82
|
+
name = ::Regexp.last_match(3)
|
|
62
83
|
offset = parse_error.location.start_offset - 1
|
|
63
84
|
parameter_position_node = generation.root_node.node_at(offset + length) || return
|
|
64
85
|
|
|
65
86
|
generation[parse_error.location.start_offset, length - 1] = ""
|
|
66
87
|
parameter_memo = generation.memo_pad.parameter_memo(parameter_position_node)
|
|
67
88
|
parameter_memo.type = type
|
|
89
|
+
parameter_memo.name = name.to_sym if name
|
|
68
90
|
parameter_memo.qualifier = "*"
|
|
69
91
|
end
|
|
70
92
|
|
|
@@ -15,9 +15,10 @@ module RubyModKit
|
|
|
15
15
|
def_parent_memo.ivars_memo.each do |name, ivar_memo|
|
|
16
16
|
offset = ivar_memo.offset || next
|
|
17
17
|
def_parent_node = generation.root_node.def_parent_node_at(offset) || next
|
|
18
|
-
body_line_offset = generation.
|
|
18
|
+
body_line_offset = generation.line_offset(def_parent_node, 1) || next
|
|
19
19
|
generation.memo_pad.flags[:rbs_annotated] = true
|
|
20
|
-
|
|
20
|
+
script = "#{ivar_memo.indent}# @rbs @#{name}: #{ivar_memo.type}\n#{ivar_memo.separator}"
|
|
21
|
+
generation[body_line_offset, 0] = script
|
|
21
22
|
end
|
|
22
23
|
end
|
|
23
24
|
true
|
|
@@ -15,8 +15,7 @@ module RubyModKit
|
|
|
15
15
|
overload_memo.correct_offset(generation.root_node)
|
|
16
16
|
offset = overload_memo.offset
|
|
17
17
|
def_node = generation.root_node.def_node_at(offset) || raise(RubyModKit::Error)
|
|
18
|
-
|
|
19
|
-
indent = generation.lines[start_line][/\A */] || ""
|
|
18
|
+
indent = generation.line_indent(def_node)
|
|
20
19
|
offset -= indent.length
|
|
21
20
|
|
|
22
21
|
annotation = +""
|
|
@@ -11,21 +11,22 @@ module RubyModKit
|
|
|
11
11
|
# @rbs generation: Generation
|
|
12
12
|
# @rbs return: bool
|
|
13
13
|
def perform(generation)
|
|
14
|
-
generation.memo_pad.
|
|
14
|
+
generation.memo_pad.each_parameter_memo do |parameter_memo|
|
|
15
15
|
next if parameter_memo.untyped?
|
|
16
16
|
|
|
17
|
+
offset = parameter_memo.offset
|
|
17
18
|
def_node = generation.root_node.def_node_at(offset)
|
|
18
19
|
raise RubyModKit::Error, "DefNode not found" if !def_node || !def_node.is_a?(Node::DefNode)
|
|
19
20
|
|
|
20
21
|
parameter_node = generation.root_node.parameter_node_at(offset)
|
|
21
22
|
raise RubyModKit::Error, "ParameterNode not found" unless parameter_node
|
|
22
23
|
|
|
24
|
+
line_offset = generation.line_offset(def_node) || raise(RubyModKit::Error)
|
|
23
25
|
type = parameter_memo.type
|
|
24
|
-
|
|
25
|
-
indent = def_node.offset - src_offset
|
|
26
|
+
indent = generation.line_indent(def_node)
|
|
26
27
|
qualified_name = "#{parameter_memo.qualifier}#{parameter_node.name}"
|
|
27
28
|
generation.memo_pad.flags[:rbs_annotated] = true
|
|
28
|
-
generation[
|
|
29
|
+
generation[line_offset, 0] = "#{indent}# @rbs #{qualified_name}: #{type}\n"
|
|
29
30
|
end
|
|
30
31
|
true
|
|
31
32
|
end
|
|
@@ -16,7 +16,7 @@ module RubyModKit
|
|
|
16
16
|
raise RubyModKit::Error, "DefNode not found" if !def_node || !def_node.is_a?(Node::DefNode)
|
|
17
17
|
next if method_memo.untyped?
|
|
18
18
|
|
|
19
|
-
src_offset = generation.
|
|
19
|
+
src_offset = generation.line_offset(def_node) || raise(RubyModKit::Error)
|
|
20
20
|
indent = offset - src_offset
|
|
21
21
|
generation.memo_pad.flags[:rbs_annotated] = true
|
|
22
22
|
generation[src_offset, 0] = "#{" " * indent}# @rbs return: #{method_memo.type}\n"
|
|
@@ -19,6 +19,7 @@ module RubyModKit
|
|
|
19
19
|
return if parse_error.location.slice != ":"
|
|
20
20
|
|
|
21
21
|
def_node = generation.root_node.statements_node_at(parse_error.location.start_offset)&.parent
|
|
22
|
+
def_node = def_node.parent if def_node.is_a?(Node::BeginNode)
|
|
22
23
|
return unless def_node.is_a?(Node::DefNode)
|
|
23
24
|
|
|
24
25
|
lparen_loc = def_node.lparen_loc
|
|
@@ -29,19 +29,13 @@ module RubyModKit
|
|
|
29
29
|
ivars_memo.keep_if { |_, ivar_memo| ivar_memo.attr_kind }
|
|
30
30
|
next if ivars_memo.empty?
|
|
31
31
|
|
|
32
|
-
add_first_separator_line = false
|
|
33
32
|
if attr_adding_line == 0
|
|
34
33
|
attr_adding_line = def_parent_node.location.start_line
|
|
35
|
-
|
|
36
|
-
while generation.line(attr_adding_line) =~ /\A\s*#.*|\A$/
|
|
37
|
-
prev_line = ::Regexp.last_match(0)
|
|
38
|
-
attr_adding_line += 1
|
|
39
|
-
end
|
|
40
|
-
add_first_separator_line = prev_line != ""
|
|
34
|
+
attr_adding_line += 1 while generation.line(attr_adding_line) =~ /\A\s*#.*|\A$/
|
|
41
35
|
end
|
|
42
36
|
line = generation.line(attr_adding_line) || next
|
|
43
37
|
add_separator_line = line != "\n" && line !~ /\A\s*end$/
|
|
44
|
-
offset = generation.
|
|
38
|
+
offset = generation.line_offset(attr_adding_line) || next
|
|
45
39
|
|
|
46
40
|
body_node = def_parent_node.body_node
|
|
47
41
|
if body_node
|
|
@@ -50,9 +44,9 @@ module RubyModKit
|
|
|
50
44
|
else
|
|
51
45
|
def_parent_line = generation.line(def_parent_node)
|
|
52
46
|
indent = " #{def_parent_line[/\A\s*/]}"
|
|
47
|
+
generation[offset, 0] = "\n"
|
|
53
48
|
end
|
|
54
49
|
|
|
55
|
-
generation[offset, 0] = "\n" if add_first_separator_line
|
|
56
50
|
ivars_memo.each do |name, ivar_memo|
|
|
57
51
|
attr = ivar_memo.attr_kind
|
|
58
52
|
attr = "#{ivar_memo.visibility} #{attr}" if ivar_memo.visibility
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
module RubyModKit
|
|
6
|
+
class Feature
|
|
7
|
+
class Type
|
|
8
|
+
class Yard
|
|
9
|
+
# The mission for parameter types
|
|
10
|
+
class TypeParameterMission < Mission
|
|
11
|
+
# @rbs generation: Generation
|
|
12
|
+
# @rbs return: bool
|
|
13
|
+
def perform(generation)
|
|
14
|
+
generation.memo_pad.each_parameter_memo do |parameter_memo|
|
|
15
|
+
next if parameter_memo.untyped?
|
|
16
|
+
|
|
17
|
+
offset = parameter_memo.offset
|
|
18
|
+
def_node = generation.root_node.def_node_at(offset)
|
|
19
|
+
raise RubyModKit::Error, "DefNode not found" if !def_node || !def_node.is_a?(Node::DefNode)
|
|
20
|
+
|
|
21
|
+
parameter_node = generation.root_node.parameter_node_at(offset)
|
|
22
|
+
raise RubyModKit::Error, "ParameterNode not found" unless parameter_node
|
|
23
|
+
|
|
24
|
+
line_offset = generation.line_offset(def_node) || raise(RubyModKit::Error)
|
|
25
|
+
indent = generation.line_indent(def_node)
|
|
26
|
+
script = "#{indent}# @param #{parameter_node.name} [#{Yard.rbs2yard(parameter_memo.type)}]\n"
|
|
27
|
+
generation[line_offset, 0] = script
|
|
28
|
+
end
|
|
29
|
+
true
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
module RubyModKit
|
|
6
|
+
class Feature
|
|
7
|
+
class Type
|
|
8
|
+
class Yard
|
|
9
|
+
# The mission for return value type
|
|
10
|
+
class TypeReturnMission < Mission
|
|
11
|
+
# @rbs generation: Generation
|
|
12
|
+
# @rbs return: bool
|
|
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)
|
|
16
|
+
raise RubyModKit::Error, "DefNode not found" if !def_node || !def_node.is_a?(Node::DefNode)
|
|
17
|
+
next if method_memo.untyped?
|
|
18
|
+
|
|
19
|
+
src_offset = generation.line_offset(def_node) || raise(RubyModKit::Error)
|
|
20
|
+
indent = offset - src_offset
|
|
21
|
+
generation.memo_pad.flags[:rbs_annotated] = true
|
|
22
|
+
generation[src_offset, 0] = "#{" " * indent}# @return [#{Yard.rbs2yard(method_memo.type)}]\n"
|
|
23
|
+
end
|
|
24
|
+
true
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
module RubyModKit
|
|
6
|
+
class Feature
|
|
7
|
+
class Type
|
|
8
|
+
# namespace for type with rbs-line feature
|
|
9
|
+
class Yard < Feature
|
|
10
|
+
# @rbs return: Array[Mission]
|
|
11
|
+
def create_missions
|
|
12
|
+
[
|
|
13
|
+
TypeParameterMission.new,
|
|
14
|
+
TypeReturnMission.new,
|
|
15
|
+
]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
class << self
|
|
19
|
+
# @rbs type: String
|
|
20
|
+
# @rbs return: String
|
|
21
|
+
def rbs2yard(type)
|
|
22
|
+
type.gsub(/\s*\|\s*/, ", ").tr("[]", "<>").gsub(/(?<=^|\W)bool(?=$|\W)/, "Boolean")
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
require_relative "yard/type_parameter_mission"
|
|
31
|
+
require_relative "yard/type_return_mission"
|