ruby_mod_kit 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +21 -0
  3. data/README.md +99 -0
  4. data/examples/user.rb +83 -0
  5. data/examples/user.rbm +47 -0
  6. data/exe/ruby_mod_kit +5 -0
  7. data/lib/ruby_mod_kit/cli.rb +27 -0
  8. data/lib/ruby_mod_kit/generation.rb +170 -0
  9. data/lib/ruby_mod_kit/memo/class.rb +27 -0
  10. data/lib/ruby_mod_kit/memo/ivar.rb +42 -0
  11. data/lib/ruby_mod_kit/memo/method.rb +49 -0
  12. data/lib/ruby_mod_kit/memo/offset_memo.rb +26 -0
  13. data/lib/ruby_mod_kit/memo/parameter.rb +39 -0
  14. data/lib/ruby_mod_kit/memo.rb +73 -0
  15. data/lib/ruby_mod_kit/mission/fix_parse_error.rb +213 -0
  16. data/lib/ruby_mod_kit/mission/ivar_arg.rb +42 -0
  17. data/lib/ruby_mod_kit/mission/overload.rb +73 -0
  18. data/lib/ruby_mod_kit/mission/type_attr.rb +75 -0
  19. data/lib/ruby_mod_kit/mission/type_parameter.rb +39 -0
  20. data/lib/ruby_mod_kit/mission/type_return.rb +33 -0
  21. data/lib/ruby_mod_kit/mission.rb +40 -0
  22. data/lib/ruby_mod_kit/node/call_node.rb +30 -0
  23. data/lib/ruby_mod_kit/node/class_node.rb +37 -0
  24. data/lib/ruby_mod_kit/node/def_node.rb +57 -0
  25. data/lib/ruby_mod_kit/node/parameter_node.rb +42 -0
  26. data/lib/ruby_mod_kit/node/program_node.rb +23 -0
  27. data/lib/ruby_mod_kit/node/statements_node.rb +27 -0
  28. data/lib/ruby_mod_kit/node/symbol_node.rb +34 -0
  29. data/lib/ruby_mod_kit/node/untyped_node.rb +25 -0
  30. data/lib/ruby_mod_kit/node.rb +164 -0
  31. data/lib/ruby_mod_kit/offset_diff.rb +37 -0
  32. data/lib/ruby_mod_kit/transpiler.rb +20 -0
  33. data/lib/ruby_mod_kit/version.rb +7 -0
  34. data/lib/ruby_mod_kit.rb +59 -0
  35. data/ruby_mod_kit.gemspec +51 -0
  36. data/sig/generated/examples/user.rbs +60 -0
  37. data/sig/generated/ruby_mod_kit/cli.rbs +14 -0
  38. data/sig/generated/ruby_mod_kit/generation.rbs +101 -0
  39. data/sig/generated/ruby_mod_kit/memo/class.rbs +20 -0
  40. data/sig/generated/ruby_mod_kit/memo/ivar.rbs +30 -0
  41. data/sig/generated/ruby_mod_kit/memo/located.rbs +14 -0
  42. data/sig/generated/ruby_mod_kit/memo/method.rbs +37 -0
  43. data/sig/generated/ruby_mod_kit/memo/offset_memo.rbs +20 -0
  44. data/sig/generated/ruby_mod_kit/memo/parameter.rbs +33 -0
  45. data/sig/generated/ruby_mod_kit/memo/parameter_type.rbs +14 -0
  46. data/sig/generated/ruby_mod_kit/memo.rbs +41 -0
  47. data/sig/generated/ruby_mod_kit/mission/fix_parse_error.rbs +73 -0
  48. data/sig/generated/ruby_mod_kit/mission/ivar_arg.rbs +19 -0
  49. data/sig/generated/ruby_mod_kit/mission/overload.rbs +20 -0
  50. data/sig/generated/ruby_mod_kit/mission/type_attr.rbs +18 -0
  51. data/sig/generated/ruby_mod_kit/mission/type_parameter.rbs +18 -0
  52. data/sig/generated/ruby_mod_kit/mission/type_return.rbs +18 -0
  53. data/sig/generated/ruby_mod_kit/mission.rbs +25 -0
  54. data/sig/generated/ruby_mod_kit/node/call_node.rbs +25 -0
  55. data/sig/generated/ruby_mod_kit/node/class_node.rbs +29 -0
  56. data/sig/generated/ruby_mod_kit/node/def_node.rbs +39 -0
  57. data/sig/generated/ruby_mod_kit/node/parameter_node.rbs +26 -0
  58. data/sig/generated/ruby_mod_kit/node/program_node.rbs +16 -0
  59. data/sig/generated/ruby_mod_kit/node/statements_node.rbs +21 -0
  60. data/sig/generated/ruby_mod_kit/node/symbol_node.rbs +24 -0
  61. data/sig/generated/ruby_mod_kit/node/untyped_node.rbs +21 -0
  62. data/sig/generated/ruby_mod_kit/node.rbs +63 -0
  63. data/sig/generated/ruby_mod_kit/offset_diff.rbs +20 -0
  64. data/sig/generated/ruby_mod_kit/transpiler.rbs +11 -0
  65. data/sig/generated/ruby_mod_kit/version.rbs +5 -0
  66. data/sig/generated/ruby_mod_kit.rbs +33 -0
  67. data/sig/sorted_set.rbs +8 -0
  68. data/sig/thor.rbs +3 -0
  69. metadata +157 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e3a08a3d1865aa1abd27922326dc12e4cfc6c9a621f0c73882a64c12a80cc3d4
4
+ data.tar.gz: d30dd20e654a68c233f33925f6f27938a3920675df07dea1377f31ba8fa42ab6
5
+ SHA512:
6
+ metadata.gz: cc67818cecc1c39a1aaf1f925a8ebd59dab9220a77e0d1e2dd19be99ea7b8b72e582e4a8d794966ab411125b229084f339f85cd427eebf33e29f88ee576eb111
7
+ data.tar.gz: ed11c866fba06fe283e1957ba41c2138194cdc3d5049dfe9cefdee662519d3e222ef5ac8b9b5f491e579fef4db049c11b3b46074f5f7fe8585c7cf2c84ab94d5
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2024 wanabe
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,99 @@
1
+ # RubyModKit
2
+
3
+ RubyModKit is a transpiler tool from Ruby-like syntax script to Ruby script.
4
+ The name is shorthand for ruby-modify-kit.
5
+
6
+ ## Installation
7
+
8
+ Install the gem and add to the application's Gemfile by executing:
9
+
10
+ $ bundle add ruby_mod_kit
11
+
12
+ If bundler is not being used to manage dependencies, install the gem by executing:
13
+
14
+ $ gem install ruby_mod_kit
15
+
16
+ ## Usage
17
+
18
+ ### as command line tool
19
+
20
+ #### `transpile`
21
+
22
+ You can get transpiled ruby script from .rbm file by `ruby_mod_kit transpile` command.
23
+
24
+ ```
25
+ ruby_mod_kit transpile path/to/script.rbm
26
+ ```
27
+
28
+ #### `exec`
29
+
30
+ You can run transpiled ruby script by `ruby_mod_kit exec` command.
31
+
32
+ ```
33
+ ruby_mod_kit transpile path/to/script.rbm
34
+ ```
35
+
36
+ The command also creates/updates ruby script before running.
37
+
38
+ ## Feature
39
+
40
+ 1. Type definition
41
+ - The deifinitions will be changed to RBS-inline annotation comments.
42
+ - Instance variables
43
+ - `@foo: Foo` -> `# @rbs @foo: Foo`
44
+ - Attributes (`attr_reader`, `attr_writer`, `attr_accessor`)
45
+ - `attr_reader @foo: Foo` -> `# @rbs @foo: Foo` and `attr_reader :foo #: Foo`
46
+ - `getter`, `setter`, `property` are also available
47
+ - Method parameters
48
+ - `def foo(Bar => bar) ... end` -> `# @rbs foo: Foo` and `def foo(bar) ... end`
49
+ - Method return values
50
+ - `def foo(bar): Foo ... end` -> `# @rbs return: Foo` and `def foo(bar) ... end`
51
+ 2. Instance variable parameter
52
+ - `def foo(@bar) ... end` -> `def foo(bar) @bar = bar ... end`
53
+ 3. Overloading
54
+ - ```
55
+ def foo(Bar => arg): void
56
+ ...
57
+ end
58
+
59
+ def foo(Buz => arg): Buz
60
+ ...
61
+ end
62
+ ```
63
+ ->
64
+ ```
65
+ # @rbs (Bar) -> void
66
+ # | (Buz) -> Buz
67
+ def foo(*args)
68
+ case args
69
+ in [Bar]
70
+ foo__overload0(*args)
71
+ in [Buz]
72
+ foo__overload1(*args)
73
+ end
74
+ end
75
+
76
+ # @rbs arg: Bar
77
+ # @rbs return: void
78
+ def foo__overload0(Bar => arg)
79
+ ...
80
+ end
81
+
82
+ # @rbs arg: Buz
83
+ # @rbs return: Buz
84
+ def foo__overload1(Buz => arg)
85
+ ...
86
+ end
87
+ ```
88
+
89
+ ## Development
90
+
91
+ TODO
92
+
93
+ ## Contributing
94
+
95
+ Bug reports and pull requests are welcome on GitHub at https://github.com/wanabe/ruby_mod_kit.
96
+
97
+ ## License
98
+
99
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/examples/user.rb ADDED
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ # Example class
6
+ class User
7
+ # @rbs @email: String
8
+ # @rbs @tel: nil | String
9
+ # @rbs @name: nil | String
10
+ # @rbs @nick: nil | String
11
+
12
+ attr_reader :email #: String
13
+ attr_reader :name #: nil | String
14
+ attr_reader :nick #: nil | String
15
+
16
+ # @rbs email: String
17
+ # @rbs tel: nil | String
18
+ # @rbs name: nil | String
19
+ # @rbs nick: nil | String
20
+ # @rbs return: void
21
+ def initialize(email, tel = nil, name: nil, nick: nil)
22
+ @email = email
23
+ @tel = tel
24
+ @name = name
25
+ @nick = nick
26
+ end
27
+ end
28
+
29
+ # Example class
30
+ class Pos
31
+ # @rbs @x: Integer
32
+ # @rbs @y: Integer
33
+ # @rbs @z: Integer
34
+
35
+ attr_reader :x #: Integer
36
+ attr_reader :y #: Integer
37
+ attr_reader :z #: Integer
38
+
39
+ # @rbs x: Integer
40
+ # @rbs y: Integer
41
+ # @rbs z: Integer
42
+ # @rbs return: void
43
+ def initialize(x, y, z = 0)
44
+ @x = x
45
+ @y = y
46
+ @z = z
47
+ end
48
+
49
+ # @rbs (Pos) -> Integer
50
+ # | (Integer) -> Pos
51
+ def *(*args)
52
+ case args
53
+ in [Pos]
54
+ _mul__overload0(*args)
55
+ in [Integer]
56
+ _mul__overload1(*args)
57
+ end
58
+ end
59
+
60
+ # @rbs other: Pos
61
+ # @rbs return: Integer
62
+ def _mul__overload0(other)
63
+ (@x * other.x) + (@y * other.y) + (@z * other.z)
64
+ end
65
+
66
+ # @rbs n: Integer
67
+ # @rbs return: Pos
68
+ def _mul__overload1(n)
69
+ Pos.new(@x * n, @y * n, @z * n)
70
+ end
71
+
72
+ # @rbs return: String
73
+ def to_s
74
+ "#<Pos: (#{@x}, #{@y}, #{@z})>"
75
+ end
76
+ end
77
+
78
+ puts(
79
+ User.new("a@exmple.com").email,
80
+ Pos.new(2, 3).y,
81
+ Pos.new(1, 2) * Pos.new(3, 4),
82
+ Pos.new(1, 2) * 3,
83
+ )
data/examples/user.rbm ADDED
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ # Example class
6
+ class User
7
+ attr_reader @email: String
8
+ @tel: (nil | String)
9
+ attr_reader @name: (nil | String)
10
+ attr_reader @nick: (nil | String)
11
+
12
+ def initialize(@email, @tel = nil, @name: nil, @nick: nil): void
13
+ end
14
+ end
15
+
16
+ # Example class
17
+ class Pos
18
+ @x: Integer
19
+ @y: Integer
20
+ @z: Integer
21
+
22
+ attr_reader :x
23
+ attr_reader :y
24
+ attr_reader :z
25
+
26
+ def initialize(@x, @y, @z = 0): void
27
+ end
28
+
29
+ def *(Pos => other): Integer
30
+ (@x * other.x) + (@y * other.y) + (@z * other.z)
31
+ end
32
+
33
+ def *(Integer => n): Pos
34
+ Pos.new(@x * n, @y * n, @z * n)
35
+ end
36
+
37
+ def to_s: String
38
+ "#<Pos: (#{@x}, #{@y}, #{@z})>"
39
+ end
40
+ end
41
+
42
+ puts(
43
+ User.new("a@exmple.com").email,
44
+ Pos.new(2, 3).y,
45
+ Pos.new(1, 2) * Pos.new(3, 4),
46
+ Pos.new(1, 2) * 3,
47
+ )
data/exe/ruby_mod_kit ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "ruby_mod_kit/cli"
5
+ RubyModKit::CLI.start
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ require "ruby_mod_kit"
6
+ require "thor"
7
+
8
+ module RubyModKit
9
+ # This class provides CLI commands of ruby_mod_kit.
10
+ class CLI < Thor
11
+ desc "exec", "execute rbm file"
12
+ # @rbs *args: String
13
+ # @rbs return: void
14
+ def exec(*args)
15
+ RubyModKit.execute_file(*args)
16
+ end
17
+
18
+ desc "transpile", "transpile rbm files"
19
+ # @rbs *args: String
20
+ # @rbs return: void
21
+ def transpile(*args)
22
+ args.each do |path|
23
+ RubyModKit.transpile_file(path)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,170 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module RubyModKit
6
+ # The class of transpiler generation.
7
+ class Generation
8
+ # @rbs @parse_result: Prism::ParseResult
9
+ # @rbs @script: String
10
+ # @rbs @missions: Array[Mission]
11
+ # @rbs @memo: Memo
12
+ # @rbs @root_node: Node::ProgramNode
13
+ # @rbs @offset_diff: OffsetDiff
14
+ # @rbs @generation_num: Integer
15
+ # @rbs @filename: String | nil
16
+
17
+ attr_reader :parse_result #: Prism::ParseResult
18
+ attr_reader :script #: String
19
+
20
+ # @rbs script: String
21
+ # @rbs missions: Array[Mission]
22
+ # @rbs memo: Memo
23
+ # @rbs generation_num: Integer
24
+ # @rbs filename: String | nil
25
+ # @rbs return: void
26
+ def initialize(script, missions: [], memo: Memo.new, generation_num: 0, filename: nil)
27
+ @script = script
28
+ @missions = missions
29
+ @memo = memo
30
+ @generation_num = generation_num
31
+ @filename = filename
32
+ @offset_diff = OffsetDiff.new
33
+ @parse_result = Prism.parse(@script)
34
+ @root_node = Node::ProgramNode.new(@parse_result.value)
35
+ init_missions
36
+ end
37
+
38
+ # @rbs return: void
39
+ def init_missions
40
+ return unless first_generation?
41
+
42
+ add_mission(Mission::FixParseError.new)
43
+ add_mission(Mission::TypeAttr.new)
44
+ add_mission(Mission::Overload.new)
45
+ add_mission(Mission::TypeParameter.new)
46
+ add_mission(Mission::TypeReturn.new)
47
+ end
48
+
49
+ # @rbs return: bool
50
+ def first_generation?
51
+ @generation_num == 0
52
+ end
53
+
54
+ # @rbs return: Generation
55
+ def succ
56
+ @missions.each do |mission|
57
+ mission.succ(@offset_diff)
58
+ end
59
+ @memo.succ(@offset_diff)
60
+ Generation.new(
61
+ @script,
62
+ missions: @missions,
63
+ memo: @memo,
64
+ generation_num: @generation_num + 1,
65
+ filename: @filename,
66
+ )
67
+ end
68
+
69
+ # @rbs return: String
70
+ def name
71
+ "#{@filename || "(eval)"}[gen #{@generation_num}]"
72
+ end
73
+
74
+ # @rbs return: void
75
+ def resolve
76
+ perform_missions
77
+ end
78
+
79
+ # @rbs return: bool
80
+ def completed?
81
+ @parse_result.errors.empty? && @missions.empty?
82
+ end
83
+
84
+ # @rbs src_offset: Integer
85
+ # @rbs length: Integer
86
+ # @rbs str: String
87
+ # @rbs return: String
88
+ def []=(src_offset, length, str)
89
+ diff = str.length - length
90
+ @script[@offset_diff[src_offset], length] = str
91
+ @offset_diff.insert(src_offset, diff)
92
+ end
93
+
94
+ # @rbs src_range: Range[Integer]
95
+ # @rbs return: String
96
+ def [](src_range)
97
+ dst_range = Range.new(@offset_diff[src_range.first], @offset_diff[src_range.last], src_range.exclude_end?)
98
+ @script[dst_range] || raise(RubyModKit::Error, "Invalid range")
99
+ end
100
+
101
+ # @rbs (Integer) -> String
102
+ # | (Node) -> String
103
+ # | (Prism::ParseError) -> String
104
+ def line(*args)
105
+ case args
106
+ in [Integer]
107
+ line__overload0(*args)
108
+ in [Node]
109
+ line__overload1(*args)
110
+ in [Prism::ParseError]
111
+ line__overload2(*args)
112
+ end
113
+ end
114
+
115
+ # @rbs line_num: Integer
116
+ # @rbs return: String
117
+ def line__overload0(line_num)
118
+ offset = @offset_diff[@parse_result.source.offsets[line_num]]
119
+ (@script.match(/.*\n?/, offset) && Regexp.last_match(0)) || raise(RubyModKit::Error)
120
+ end
121
+
122
+ # @rbs node: Node
123
+ # @rbs return: String
124
+ def line__overload1(node)
125
+ line(node.prism_node.location.start_line - 1)
126
+ end
127
+
128
+ # @rbs parse_error: Prism::ParseError
129
+ # @rbs return: String
130
+ def line__overload2(parse_error)
131
+ line(parse_error.location.start_line - 1)
132
+ end
133
+
134
+ # @rbs (Integer) -> (Integer | nil)
135
+ # | (Prism::ParseError) -> (Integer | nil)
136
+ def src_offset(*args)
137
+ case args
138
+ in [Integer]
139
+ src_offset__overload0(*args)
140
+ in [Prism::ParseError]
141
+ src_offset__overload1(*args)
142
+ end
143
+ end
144
+
145
+ # @rbs line_num: Integer
146
+ # @rbs return: Integer | nil
147
+ def src_offset__overload0(line_num)
148
+ parse_result.source.offsets[line_num]
149
+ end
150
+
151
+ # @rbs parse_error: Prism::ParseError
152
+ # @rbs return: Integer | nil
153
+ def src_offset__overload1(parse_error)
154
+ src_offset(parse_error.location.start_line - 1)
155
+ end
156
+
157
+ # @rbs return: void
158
+ def perform_missions
159
+ @missions.delete_if do |mission|
160
+ mission.perform(self, @root_node, @parse_result, @memo) || break
161
+ end
162
+ end
163
+
164
+ # @rbs mission: Mission
165
+ # @rbs return: void
166
+ def add_mission(mission)
167
+ @missions << mission
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module RubyModKit
6
+ class Memo
7
+ # The memo for parameter type
8
+ class Class < OffsetMemo
9
+ # @rbs @ivars_memo: Hash[Symbol, Memo::Ivar]
10
+
11
+ attr_reader :ivars_memo #: Hash[Symbol, Memo::Ivar]
12
+
13
+ # @rbs class_node: Node::ClassNode
14
+ # @rbs return: void
15
+ def initialize(class_node)
16
+ @ivars_memo = {}
17
+ super(class_node.offset)
18
+ end
19
+
20
+ # @rbs name: Symbol
21
+ # @rbs return: Memo::Ivar
22
+ def ivar_memo(name)
23
+ @ivars_memo[name] ||= Memo::Ivar.new(name)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module RubyModKit
6
+ class Memo
7
+ # The memo for parameter type
8
+ class Ivar
9
+ # @rbs @type: nil | String
10
+ # @rbs @attr_kind: nil | Symbol
11
+ # @rbs @name: Symbol
12
+
13
+ attr_reader :type #: nil | String
14
+ attr_reader :attr_kind #: nil | Symbol
15
+
16
+ # @rbs name: Symbol
17
+ # @rbs return: void
18
+ def initialize(name)
19
+ @name = name
20
+ end
21
+
22
+ # @rbs type: String
23
+ # @rbs return: void
24
+ def type=(type)
25
+ @type = Memo.unify_type(type)
26
+ end
27
+
28
+ # @rbs kind: Symbol | String
29
+ # @rbs return: void
30
+ def attr_kind=(kind)
31
+ case kind.to_sym
32
+ when :attr_reader, :reader, :getter
33
+ @attr_kind = :attr_reader
34
+ when :attr_writer, :writer, :setter
35
+ @attr_kind = :attr_writer
36
+ when :attr_accessor, :accessor, :property
37
+ @attr_kind = :attr_accessor
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module RubyModKit
6
+ class Memo
7
+ # The memo for parameter type
8
+ class Method < OffsetMemo
9
+ # @rbs @name: Symbol
10
+ # @rbs @parameters: Set[Memo::Parameter]
11
+ # @rbs @type: String
12
+
13
+ attr_reader :name #: Symbol
14
+ attr_reader :parameters #: Set[Memo::Parameter]
15
+ attr_reader :type #: String
16
+
17
+ UNTYPED = "untyped"
18
+
19
+ # @rbs node: Node::DefNode
20
+ # @rbs return: void
21
+ def initialize(node)
22
+ @type = UNTYPED
23
+ @parameters = Set.new
24
+ @name = node.name
25
+ raise RubyModKit::Error unless node.parent
26
+
27
+ super(node.offset)
28
+ end
29
+
30
+ # @rbs parameter_memo: Memo::Parameter
31
+ # @rbs return: Memo::Parameter
32
+ def add_parameter(parameter_memo)
33
+ @parameters << parameter_memo
34
+ parameter_memo
35
+ end
36
+
37
+ # @rbs return: bool
38
+ def untyped?
39
+ @type == UNTYPED
40
+ end
41
+
42
+ # @rbs type: String
43
+ # @rbs return: void
44
+ def type=(type)
45
+ @type = Memo.unify_type(type)
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module RubyModKit
6
+ class Memo
7
+ # The base class for located memo
8
+ class OffsetMemo
9
+ # @rbs @offset: Integer
10
+
11
+ attr_reader :offset #: Integer
12
+
13
+ # @rbs offset: Integer
14
+ # @rbs return: void
15
+ def initialize(offset)
16
+ @offset = offset
17
+ end
18
+
19
+ # @rbs offset_diff: OffsetDiff
20
+ # @rbs return: void
21
+ def succ(offset_diff)
22
+ @offset = offset_diff[@offset]
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module RubyModKit
6
+ class Memo
7
+ # The memo for parameter type
8
+ class Parameter < OffsetMemo
9
+ # @rbs @type: String
10
+ # @rbs @ivar_parameter: bool
11
+ # @rbs @qualifier: String
12
+
13
+ attr_reader :type #: String
14
+ attr_accessor :ivar_parameter #: bool
15
+ attr_accessor :qualifier #: String
16
+
17
+ UNTYPED = "untyped"
18
+
19
+ # @rbs offset: Integer
20
+ # @rbs return: void
21
+ def initialize(offset)
22
+ @type = UNTYPED
23
+ @ivar_parameter = false
24
+ super
25
+ end
26
+
27
+ # @rbs return: bool
28
+ def untyped?
29
+ @type == UNTYPED
30
+ end
31
+
32
+ # @rbs type: String
33
+ # @rbs return: void
34
+ def type=(type)
35
+ @type = Memo.unify_type(type)
36
+ end
37
+ end
38
+ end
39
+ end