ruby_mod_kit 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.ruby_mod_kit.yml +5 -0
- data/lib/ruby_mod_kit/cli.rb +17 -2
- data/lib/ruby_mod_kit/config.rb +53 -0
- data/lib/ruby_mod_kit/core_ext/eval.rb +6 -0
- data/lib/ruby_mod_kit/core_ext/load.rb +12 -4
- data/lib/ruby_mod_kit/core_ext.rb +2 -2
- data/lib/ruby_mod_kit/corrector.rb +20 -0
- data/lib/ruby_mod_kit/corrector_manager.rb +64 -0
- data/lib/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_corrector.rb +40 -0
- data/lib/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_mission.rb +42 -0
- data/lib/ruby_mod_kit/feature/instance_variable_parameter.rb +27 -0
- data/lib/ruby_mod_kit/feature/overload/overload_mission.rb +77 -0
- data/lib/ruby_mod_kit/feature/overload.rb +19 -0
- data/lib/ruby_mod_kit/feature/type/instance_variable_colon_corrector.rb +52 -0
- data/lib/ruby_mod_kit/feature/type/parameter_arrow_corrector.rb +84 -0
- data/lib/ruby_mod_kit/feature/type/rbs_inline/add_magic_comment_mission.rb +49 -0
- data/lib/ruby_mod_kit/feature/type/rbs_inline/type_attr_mission.rb +46 -0
- data/lib/ruby_mod_kit/feature/type/rbs_inline/type_instance_variable_mission.rb +29 -0
- data/lib/ruby_mod_kit/feature/type/rbs_inline/type_overload_mission.rb +41 -0
- data/lib/ruby_mod_kit/feature/type/rbs_inline/type_parameter_mission.rb +36 -0
- data/lib/ruby_mod_kit/feature/type/rbs_inline/type_return_mission.rb +30 -0
- data/lib/ruby_mod_kit/feature/type/rbs_inline.rb +32 -0
- data/lib/ruby_mod_kit/feature/type/return_value_colon_corrector.rb +43 -0
- data/lib/ruby_mod_kit/feature/type/type_attr_mission.rb +69 -0
- data/lib/ruby_mod_kit/feature/type.rb +31 -0
- data/lib/ruby_mod_kit/feature.rb +18 -0
- data/lib/ruby_mod_kit/generation.rb +76 -29
- data/lib/ruby_mod_kit/memo/def_parent_memo.rb +36 -0
- data/lib/ruby_mod_kit/memo/{ivar.rb → ivar_memo.rb} +19 -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 +47 -0
- data/lib/ruby_mod_kit/memo/{parameter.rb → parameter_memo.rb} +3 -3
- data/lib/ruby_mod_kit/memo.rb +7 -66
- data/lib/ruby_mod_kit/memo_pad.rb +72 -0
- data/lib/ruby_mod_kit/mission.rb +3 -25
- data/lib/ruby_mod_kit/node/base_node.rb +155 -0
- data/lib/ruby_mod_kit/node/call_node.rb +11 -7
- data/lib/ruby_mod_kit/node/def_node.rb +11 -7
- data/lib/ruby_mod_kit/node/def_parent_node.rb +25 -14
- data/lib/ruby_mod_kit/node/parameter_node.rb +13 -9
- data/lib/ruby_mod_kit/node/program_node.rb +8 -3
- data/lib/ruby_mod_kit/node/statements_node.rb +11 -7
- data/lib/ruby_mod_kit/node/symbol_node.rb +12 -7
- data/lib/ruby_mod_kit/node/untyped_node.rb +11 -7
- data/lib/ruby_mod_kit/node/wrap.rb +43 -0
- data/lib/ruby_mod_kit/node.rb +4 -150
- data/lib/ruby_mod_kit/version.rb +1 -1
- data/lib/ruby_mod_kit.rb +27 -8
- data/ruby_mod_kit.gemspec +7 -1
- data/sig/generated/ruby_mod_kit/cli.rbs +5 -0
- data/sig/generated/ruby_mod_kit/config.rbs +21 -0
- data/sig/generated/ruby_mod_kit/core_ext/eval.rbs +3 -0
- data/sig/generated/ruby_mod_kit/core_ext/load.rbs +7 -4
- data/sig/generated/ruby_mod_kit/corrector.rbs +14 -0
- data/sig/generated/ruby_mod_kit/corrector_manager.rbs +22 -0
- data/sig/generated/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_corrector.rbs +18 -0
- data/sig/generated/ruby_mod_kit/feature/instance_variable_parameter/instance_variable_parameter_mission.rbs +14 -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 +21 -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 +24 -0
- data/sig/generated/ruby_mod_kit/feature/type/parameter_arrow_corrector.rbs +33 -0
- data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/add_magic_comment_mission.rbs +21 -0
- data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_attr_mission.rbs +16 -0
- data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_instance_variable_mission.rbs +16 -0
- data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_overload_mission.rbs +16 -0
- data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_parameter_mission.rbs +16 -0
- data/sig/generated/ruby_mod_kit/feature/type/rbs_inline/type_return_mission.rbs +16 -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 +18 -0
- data/sig/generated/ruby_mod_kit/feature/type/type_attr_mission.rbs +19 -0
- data/sig/generated/ruby_mod_kit/feature/type.rbs +14 -0
- data/sig/generated/ruby_mod_kit/feature.rbs +12 -0
- data/sig/generated/ruby_mod_kit/generation.rbs +44 -13
- 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} +19 -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 +34 -0
- data/sig/generated/ruby_mod_kit/memo/{parameter.rbs → parameter_memo.rbs} +3 -3
- data/sig/generated/ruby_mod_kit/memo_pad.rbs +50 -0
- data/sig/generated/ruby_mod_kit/mission.rbs +2 -13
- data/sig/generated/ruby_mod_kit/node/base_node.rbs +75 -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 +17 -10
- data/sig/generated/ruby_mod_kit/node/parameter_node.rbs +13 -8
- data/sig/generated/ruby_mod_kit/node/program_node.rbs +5 -2
- data/sig/generated/ruby_mod_kit/node/statements_node.rbs +11 -6
- data/sig/generated/ruby_mod_kit/node/symbol_node.rbs +13 -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.rbs +10 -3
- data/sig/yaml.rbs +3 -0
- metadata +63 -30
- data/lib/ruby_mod_kit/memo/def_parent.rb +0 -27
- data/lib/ruby_mod_kit/mission/fix_parse_error.rb +0 -216
- 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/transpiler.rb +0 -20
- data/sig/generated/examples/user.rbs +0 -60
- data/sig/generated/ruby_mod_kit/memo/def_parent.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/memo.rbs +0 -41
- 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.rbs +0 -63
- data/sig/generated/ruby_mod_kit/transpiler.rbs +0 -11
|
@@ -0,0 +1,46 @@
|
|
|
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 return: bool
|
|
13
|
+
def perform(generation)
|
|
14
|
+
generation.memo_pad.def_parents_memo.each_value do |def_parent_memo|
|
|
15
|
+
ivars_memo = def_parent_memo.ivars_memo.dup
|
|
16
|
+
def_parent_node = generation.root_node.def_parent_node_at(def_parent_memo.offset)
|
|
17
|
+
raise(RubyModKit::Error) unless def_parent_node
|
|
18
|
+
|
|
19
|
+
def_parent_node.body_node&.children&.each do |call_node|
|
|
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
|
|
26
|
+
next unless call_node.is_a?(Node::CallNode)
|
|
27
|
+
next unless %i[attr_reader attr_writer attr_accessor].include?(call_node.name)
|
|
28
|
+
|
|
29
|
+
argument_nodes = call_node.children[0].children
|
|
30
|
+
next if argument_nodes.size != 1 || !argument_nodes[0].is_a?(Node::SymbolNode)
|
|
31
|
+
|
|
32
|
+
name = argument_nodes[0].value || next
|
|
33
|
+
ivar_memo = ivars_memo.delete(name) || next
|
|
34
|
+
line = generation.line(call_node)
|
|
35
|
+
length = line[/\A.*(#{call_node.name}\s+:#{name})(?=\n\z)/, 1]&.length || next
|
|
36
|
+
generation.memo_pad.flags[:rbs_annotated] = true
|
|
37
|
+
generation[call_node.location.start_offset + length, 0] = " #: #{ivar_memo.type}"
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
true
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
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 instance variable types
|
|
10
|
+
class TypeInstanceVariableMission < Mission
|
|
11
|
+
# @rbs generation: Generation
|
|
12
|
+
# @rbs return: bool
|
|
13
|
+
def perform(generation)
|
|
14
|
+
generation.memo_pad.def_parents_memo.each_value do |def_parent_memo|
|
|
15
|
+
def_parent_memo.ivars_memo.each do |name, ivar_memo|
|
|
16
|
+
offset = ivar_memo.offset || next
|
|
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
|
|
20
|
+
generation[body_line_offset, 0] = "#{ivar_memo.indent}# @rbs @#{name}: #{ivar_memo.type}\n"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
true
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
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 TypeOverloadMission < Mission
|
|
11
|
+
# @rbs generation: Generation
|
|
12
|
+
# @rbs return: bool
|
|
13
|
+
def perform(generation)
|
|
14
|
+
generation.memo_pad.overloads_memo.each_value do |overload_memo|
|
|
15
|
+
overload_memo.correct_offset(generation.root_node)
|
|
16
|
+
offset = overload_memo.offset
|
|
17
|
+
def_node = generation.root_node.def_node_at(offset) || raise(RubyModKit::Error)
|
|
18
|
+
start_line = def_node.location.start_line - 1
|
|
19
|
+
indent = generation.lines[start_line][/\A */] || ""
|
|
20
|
+
offset -= indent.length
|
|
21
|
+
|
|
22
|
+
annotation = +""
|
|
23
|
+
overload_memo.overload_types.each do |parameter_types, return_type|
|
|
24
|
+
annotation << if annotation.empty?
|
|
25
|
+
"# @rbs"
|
|
26
|
+
else
|
|
27
|
+
"# |"
|
|
28
|
+
end
|
|
29
|
+
annotation << " (#{parameter_types.join(", ")}) -> #{return_type}\n"
|
|
30
|
+
end
|
|
31
|
+
annotation.gsub!(/^/, indent)
|
|
32
|
+
generation.memo_pad.flags[:rbs_annotated] = true
|
|
33
|
+
generation[offset, 0] = annotation
|
|
34
|
+
end
|
|
35
|
+
true
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
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 TypeParameterMission < Mission
|
|
11
|
+
# @rbs generation: Generation
|
|
12
|
+
# @rbs return: bool
|
|
13
|
+
def perform(generation)
|
|
14
|
+
generation.memo_pad.parameters_memo.each do |offset, parameter_memo|
|
|
15
|
+
next if parameter_memo.untyped?
|
|
16
|
+
|
|
17
|
+
def_node = generation.root_node.def_node_at(offset)
|
|
18
|
+
raise RubyModKit::Error, "DefNode not found" if !def_node || !def_node.is_a?(Node::DefNode)
|
|
19
|
+
|
|
20
|
+
parameter_node = generation.root_node.parameter_node_at(offset)
|
|
21
|
+
raise RubyModKit::Error, "ParameterNode not found" unless parameter_node
|
|
22
|
+
|
|
23
|
+
type = parameter_memo.type
|
|
24
|
+
src_offset = generation.offsets[def_node.location.start_line - 1]
|
|
25
|
+
indent = def_node.offset - src_offset
|
|
26
|
+
qualified_name = "#{parameter_memo.qualifier}#{parameter_node.name}"
|
|
27
|
+
generation.memo_pad.flags[:rbs_annotated] = true
|
|
28
|
+
generation[src_offset, 0] = "#{" " * indent}# @rbs #{qualified_name}: #{type}\n"
|
|
29
|
+
end
|
|
30
|
+
true
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
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 RbsInline
|
|
9
|
+
# The mission for parameter types
|
|
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.offsets[def_node.location.start_line - 1]
|
|
20
|
+
indent = offset - src_offset
|
|
21
|
+
generation.memo_pad.flags[:rbs_annotated] = true
|
|
22
|
+
generation[src_offset, 0] = "#{" " * indent}# @rbs return: #{method_memo.type}\n"
|
|
23
|
+
end
|
|
24
|
+
true
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
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 RbsInline < Feature
|
|
10
|
+
# @rbs return: Array[Mission]
|
|
11
|
+
def create_missions
|
|
12
|
+
[
|
|
13
|
+
TypeInstanceVariableMission.new,
|
|
14
|
+
TypeAttrMission.new,
|
|
15
|
+
TypeOverloadMission.new,
|
|
16
|
+
TypeParameterMission.new,
|
|
17
|
+
TypeReturnMission.new,
|
|
18
|
+
# This mission must be the last
|
|
19
|
+
AddMagicCommentMission.new,
|
|
20
|
+
]
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
require_relative "rbs_inline/add_magic_comment_mission"
|
|
28
|
+
require_relative "rbs_inline/type_attr_mission"
|
|
29
|
+
require_relative "rbs_inline/type_instance_variable_mission"
|
|
30
|
+
require_relative "rbs_inline/type_overload_mission"
|
|
31
|
+
require_relative "rbs_inline/type_parameter_mission"
|
|
32
|
+
require_relative "rbs_inline/type_return_mission"
|
|
@@ -0,0 +1,43 @@
|
|
|
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: Some ...` -> `def foo ...`
|
|
9
|
+
class ReturnValueColonCorrector < 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 return: void
|
|
18
|
+
def correct(parse_error, generation)
|
|
19
|
+
return if parse_error.location.slice != ":"
|
|
20
|
+
|
|
21
|
+
def_node = generation.root_node.statements_node_at(parse_error.location.start_offset)&.parent
|
|
22
|
+
return unless def_node.is_a?(Node::DefNode)
|
|
23
|
+
|
|
24
|
+
lparen_loc = def_node.lparen_loc
|
|
25
|
+
rparen_loc = def_node.rparen_loc
|
|
26
|
+
if !lparen_loc && !rparen_loc
|
|
27
|
+
src_offset = def_node.name_loc.end_offset
|
|
28
|
+
elsif lparen_loc && rparen_loc && lparen_loc.slice == "(" && rparen_loc.slice == ")"
|
|
29
|
+
src_offset = rparen_loc.end_offset
|
|
30
|
+
else
|
|
31
|
+
return
|
|
32
|
+
end
|
|
33
|
+
return if generation[src_offset...parse_error.location.start_offset] !~ /\A\s*\z/
|
|
34
|
+
|
|
35
|
+
right_node = generation.root_node.node_at(parse_error.location.end_offset + 1)
|
|
36
|
+
return_type_location = right_node&.location || return_type_location
|
|
37
|
+
generation[src_offset, return_type_location.end_offset - src_offset] = ""
|
|
38
|
+
generation.memo_pad.method_memo(def_node).type = return_type_location.slice
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
module RubyModKit
|
|
6
|
+
class Feature
|
|
7
|
+
class Type
|
|
8
|
+
# The mission for parameter attributes
|
|
9
|
+
class TypeAttrMission < Mission
|
|
10
|
+
# @rbs @modified: bool
|
|
11
|
+
|
|
12
|
+
# @rbs return: void
|
|
13
|
+
def initialize
|
|
14
|
+
super
|
|
15
|
+
@modified = false
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# @rbs generation: Generation
|
|
19
|
+
# @rbs return: bool
|
|
20
|
+
def perform(generation)
|
|
21
|
+
return true if @modified
|
|
22
|
+
|
|
23
|
+
generation.memo_pad.def_parents_memo.each_value do |def_parent_memo|
|
|
24
|
+
attr_adding_line = 0
|
|
25
|
+
ivars_memo = def_parent_memo.ivars_memo.dup
|
|
26
|
+
def_parent_node = generation.root_node.def_parent_node_at(def_parent_memo.offset)
|
|
27
|
+
raise(RubyModKit::Error) unless def_parent_node
|
|
28
|
+
|
|
29
|
+
ivars_memo.keep_if { |_, ivar_memo| ivar_memo.attr_kind }
|
|
30
|
+
next if ivars_memo.empty?
|
|
31
|
+
|
|
32
|
+
add_first_separator_line = false
|
|
33
|
+
if attr_adding_line == 0
|
|
34
|
+
attr_adding_line = def_parent_node.location.start_line
|
|
35
|
+
prev_line = nil
|
|
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 != ""
|
|
41
|
+
end
|
|
42
|
+
line = generation.line(attr_adding_line) || next
|
|
43
|
+
add_separator_line = line != "\n" && line !~ /\A\s*end$/
|
|
44
|
+
offset = generation.src_offset(attr_adding_line) || next
|
|
45
|
+
|
|
46
|
+
body_node = def_parent_node.body_node
|
|
47
|
+
if body_node
|
|
48
|
+
first_line = generation.line(body_node)
|
|
49
|
+
indent = first_line[/\A\s*/] || raise(RubyModKit::Error)
|
|
50
|
+
else
|
|
51
|
+
def_parent_line = generation.line(def_parent_node)
|
|
52
|
+
indent = " #{def_parent_line[/\A\s*/]}"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
generation[offset, 0] = "\n" if add_first_separator_line
|
|
56
|
+
ivars_memo.each do |name, ivar_memo|
|
|
57
|
+
attr = ivar_memo.attr_kind
|
|
58
|
+
attr = "#{ivar_memo.visibility} #{attr}" if ivar_memo.visibility
|
|
59
|
+
generation[offset, 0] = "#{indent}#{attr} :#{name}\n"
|
|
60
|
+
end
|
|
61
|
+
@modified = true
|
|
62
|
+
generation[offset, 0] = "\n" if add_separator_line
|
|
63
|
+
end
|
|
64
|
+
!@modified
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
module RubyModKit
|
|
6
|
+
class Feature
|
|
7
|
+
# namespace for type feature
|
|
8
|
+
class Type < Feature
|
|
9
|
+
# @rbs return: Array[Corrector]
|
|
10
|
+
def create_correctors
|
|
11
|
+
[
|
|
12
|
+
InstanceVariableColonCorrector.new,
|
|
13
|
+
ParameterArrowCorrector.new,
|
|
14
|
+
ReturnValueColonCorrector.new,
|
|
15
|
+
]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# @rbs return: Array[Mission]
|
|
19
|
+
def create_missions
|
|
20
|
+
[
|
|
21
|
+
TypeAttrMission.new,
|
|
22
|
+
]
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
require_relative "type/instance_variable_colon_corrector"
|
|
29
|
+
require_relative "type/parameter_arrow_corrector"
|
|
30
|
+
require_relative "type/return_value_colon_corrector"
|
|
31
|
+
require_relative "type/type_attr_mission"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
module RubyModKit
|
|
6
|
+
# the base class of feature
|
|
7
|
+
class Feature
|
|
8
|
+
# @rbs return: Array[Corrector]
|
|
9
|
+
def create_correctors
|
|
10
|
+
[]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# @rbs return: Array[Mission]
|
|
14
|
+
def create_missions
|
|
15
|
+
[]
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -5,33 +5,53 @@
|
|
|
5
5
|
module RubyModKit
|
|
6
6
|
# The class of transpiler generation.
|
|
7
7
|
class Generation
|
|
8
|
-
# @rbs @parse_result: Prism::ParseResult
|
|
9
8
|
# @rbs @script: String
|
|
10
9
|
# @rbs @missions: Array[Mission]
|
|
11
|
-
# @rbs @
|
|
10
|
+
# @rbs @memo_pad: MemoPad
|
|
12
11
|
# @rbs @root_node: Node::ProgramNode
|
|
13
12
|
# @rbs @offset_diff: OffsetDiff
|
|
14
13
|
# @rbs @generation_num: Integer
|
|
15
14
|
# @rbs @filename: String | nil
|
|
15
|
+
# @rbs @corrector_manager: CorrectorManager
|
|
16
|
+
# @rbs @features: Array[Feature]
|
|
17
|
+
# @rbs @config: Config
|
|
18
|
+
# @rbs @errors: Array[Prism::ParseError]
|
|
19
|
+
# @rbs @lines: Array[String]
|
|
20
|
+
# @rbs @offsets: Array[Integer]
|
|
16
21
|
|
|
17
|
-
attr_reader :parse_result #: Prism::ParseResult
|
|
18
22
|
attr_reader :script #: String
|
|
23
|
+
attr_reader :memo_pad #: MemoPad
|
|
24
|
+
attr_reader :root_node #: Node::ProgramNode
|
|
25
|
+
attr_reader :errors #: Array[Prism::ParseError]
|
|
26
|
+
attr_reader :lines #: Array[String]
|
|
27
|
+
attr_reader :offsets #: Array[Integer]
|
|
19
28
|
|
|
20
29
|
# @rbs script: String
|
|
21
30
|
# @rbs missions: Array[Mission]
|
|
22
|
-
# @rbs
|
|
31
|
+
# @rbs memo_pad: MemoPad | nil
|
|
23
32
|
# @rbs generation_num: Integer
|
|
33
|
+
# @rbs config: Config | nil
|
|
24
34
|
# @rbs filename: String | nil
|
|
35
|
+
# @rbs corrector_manager: CorrectorManager | nil
|
|
36
|
+
# @rbs features: Array[Feature] | nil
|
|
25
37
|
# @rbs return: void
|
|
26
|
-
def initialize(script, missions: [],
|
|
38
|
+
def initialize(script, missions: [], memo_pad: nil, generation_num: 0, config: nil,
|
|
39
|
+
filename: nil, corrector_manager: nil, features: nil)
|
|
27
40
|
@script = script
|
|
28
41
|
@missions = missions
|
|
29
|
-
@memo = memo
|
|
30
42
|
@generation_num = generation_num
|
|
31
43
|
@filename = filename
|
|
44
|
+
@config = config || Config.new
|
|
45
|
+
@features = features || @config.features
|
|
46
|
+
|
|
47
|
+
@memo_pad = memo_pad || MemoPad.new
|
|
48
|
+
@corrector_manager = corrector_manager || CorrectorManager.new(@features)
|
|
32
49
|
@offset_diff = OffsetDiff.new
|
|
33
|
-
|
|
34
|
-
@
|
|
50
|
+
parse_result = Prism.parse(@script)
|
|
51
|
+
@errors = parse_result.errors
|
|
52
|
+
@lines = parse_result.source.lines
|
|
53
|
+
@offsets = parse_result.source.offsets
|
|
54
|
+
@root_node = Node::ProgramNode.new(parse_result.value)
|
|
35
55
|
init_missions
|
|
36
56
|
end
|
|
37
57
|
|
|
@@ -39,11 +59,11 @@ module RubyModKit
|
|
|
39
59
|
def init_missions
|
|
40
60
|
return unless first_generation?
|
|
41
61
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
62
|
+
@features.each do |feature|
|
|
63
|
+
feature.create_missions.each do |mission|
|
|
64
|
+
add_mission(mission)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
47
67
|
end
|
|
48
68
|
|
|
49
69
|
# @rbs return: bool
|
|
@@ -53,16 +73,25 @@ module RubyModKit
|
|
|
53
73
|
|
|
54
74
|
# @rbs return: Generation
|
|
55
75
|
def succ
|
|
76
|
+
if @errors.empty?
|
|
77
|
+
perform_missions
|
|
78
|
+
else
|
|
79
|
+
perform_corrector
|
|
80
|
+
end
|
|
56
81
|
@missions.each do |mission|
|
|
57
82
|
mission.succ(@offset_diff)
|
|
58
83
|
end
|
|
59
|
-
@
|
|
84
|
+
@memo_pad.succ(@offset_diff)
|
|
85
|
+
|
|
60
86
|
Generation.new(
|
|
61
87
|
@script,
|
|
62
88
|
missions: @missions,
|
|
63
|
-
|
|
89
|
+
memo_pad: @memo_pad,
|
|
64
90
|
generation_num: @generation_num + 1,
|
|
65
91
|
filename: @filename,
|
|
92
|
+
corrector_manager: @corrector_manager,
|
|
93
|
+
features: @features,
|
|
94
|
+
config: @config,
|
|
66
95
|
)
|
|
67
96
|
end
|
|
68
97
|
|
|
@@ -71,14 +100,9 @@ module RubyModKit
|
|
|
71
100
|
"#{@filename || "(eval)"}[gen #{@generation_num}]"
|
|
72
101
|
end
|
|
73
102
|
|
|
74
|
-
# @rbs return: void
|
|
75
|
-
def resolve
|
|
76
|
-
perform_missions
|
|
77
|
-
end
|
|
78
|
-
|
|
79
103
|
# @rbs return: bool
|
|
80
104
|
def completed?
|
|
81
|
-
@
|
|
105
|
+
@errors.empty? && @missions.empty?
|
|
82
106
|
end
|
|
83
107
|
|
|
84
108
|
# @rbs src_offset: Integer
|
|
@@ -98,14 +122,21 @@ module RubyModKit
|
|
|
98
122
|
@script[dst_range] || raise(RubyModKit::Error, "Invalid range")
|
|
99
123
|
end
|
|
100
124
|
|
|
125
|
+
# @rbs offset: Integer
|
|
126
|
+
# @rbs return: String
|
|
127
|
+
def line_by_offset(offset)
|
|
128
|
+
offset = @offset_diff[offset]
|
|
129
|
+
(@script.match(/.*\n?/, offset) && Regexp.last_match(0)) || raise(RubyModKit::Error)
|
|
130
|
+
end
|
|
131
|
+
|
|
101
132
|
# @rbs (Integer) -> String
|
|
102
|
-
# | (Node) -> String
|
|
133
|
+
# | (Node::BaseNode) -> String
|
|
103
134
|
# | (Prism::ParseError) -> String
|
|
104
135
|
def line(*args)
|
|
105
136
|
case args
|
|
106
137
|
in [Integer]
|
|
107
138
|
line__overload0(*args)
|
|
108
|
-
in [Node]
|
|
139
|
+
in [Node::BaseNode]
|
|
109
140
|
line__overload1(*args)
|
|
110
141
|
in [Prism::ParseError]
|
|
111
142
|
line__overload2(*args)
|
|
@@ -115,14 +146,13 @@ module RubyModKit
|
|
|
115
146
|
# @rbs line_num: Integer
|
|
116
147
|
# @rbs return: String
|
|
117
148
|
def line__overload0(line_num)
|
|
118
|
-
|
|
119
|
-
(@script.match(/.*\n?/, offset) && Regexp.last_match(0)) || raise(RubyModKit::Error)
|
|
149
|
+
line_by_offset(@offsets[line_num])
|
|
120
150
|
end
|
|
121
151
|
|
|
122
|
-
# @rbs node: Node
|
|
152
|
+
# @rbs node: Node::BaseNode
|
|
123
153
|
# @rbs return: String
|
|
124
154
|
def line__overload1(node)
|
|
125
|
-
line(node.
|
|
155
|
+
line(node.location.start_line - 1)
|
|
126
156
|
end
|
|
127
157
|
|
|
128
158
|
# @rbs parse_error: Prism::ParseError
|
|
@@ -145,7 +175,7 @@ module RubyModKit
|
|
|
145
175
|
# @rbs line_num: Integer
|
|
146
176
|
# @rbs return: Integer | nil
|
|
147
177
|
def src_offset__overload0(line_num)
|
|
148
|
-
|
|
178
|
+
@offsets[line_num]
|
|
149
179
|
end
|
|
150
180
|
|
|
151
181
|
# @rbs parse_error: Prism::ParseError
|
|
@@ -154,10 +184,15 @@ module RubyModKit
|
|
|
154
184
|
src_offset(parse_error.location.start_line - 1)
|
|
155
185
|
end
|
|
156
186
|
|
|
187
|
+
# @rbs return: void
|
|
188
|
+
def perform_corrector
|
|
189
|
+
@corrector_manager.perform(self)
|
|
190
|
+
end
|
|
191
|
+
|
|
157
192
|
# @rbs return: void
|
|
158
193
|
def perform_missions
|
|
159
194
|
@missions.delete_if do |mission|
|
|
160
|
-
mission.perform(self
|
|
195
|
+
mission.perform(self) || break
|
|
161
196
|
end
|
|
162
197
|
end
|
|
163
198
|
|
|
@@ -166,5 +201,17 @@ module RubyModKit
|
|
|
166
201
|
def add_mission(mission)
|
|
167
202
|
@missions << mission
|
|
168
203
|
end
|
|
204
|
+
|
|
205
|
+
class << self
|
|
206
|
+
# @rbs src: String
|
|
207
|
+
# @rbs filename: String | nil
|
|
208
|
+
# @rbs config: Config | nil
|
|
209
|
+
# @rbs return: Generation
|
|
210
|
+
def resolve(src, filename: nil, config: nil)
|
|
211
|
+
generation = Generation.new(src.dup, filename: filename, config: config)
|
|
212
|
+
generation = generation.succ until generation.completed?
|
|
213
|
+
generation
|
|
214
|
+
end
|
|
215
|
+
end
|
|
169
216
|
end
|
|
170
217
|
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
module RubyModKit
|
|
6
|
+
module Memo
|
|
7
|
+
# The memo for def parent (class, module)
|
|
8
|
+
class DefParentMemo < OffsetMemo
|
|
9
|
+
# @rbs @ivars_memo: Hash[Symbol, Memo::IvarMemo]
|
|
10
|
+
|
|
11
|
+
attr_reader :ivars_memo #: Hash[Symbol, Memo::IvarMemo]
|
|
12
|
+
|
|
13
|
+
# @rbs def_parent_node: Node::DefParentNode
|
|
14
|
+
# @rbs return: void
|
|
15
|
+
def initialize(def_parent_node)
|
|
16
|
+
@ivars_memo = {}
|
|
17
|
+
super(def_parent_node.offset)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# @rbs name: Symbol
|
|
21
|
+
# @rbs return: Memo::IvarMemo
|
|
22
|
+
def ivar_memo(name)
|
|
23
|
+
@ivars_memo[name] ||= Memo::IvarMemo.new(name)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @rbs offset_diff: OffsetDiff
|
|
27
|
+
# @rbs return: void
|
|
28
|
+
def succ(offset_diff)
|
|
29
|
+
@ivars_memo.each_value do |ivar_memo|
|
|
30
|
+
ivar_memo.succ(offset_diff)
|
|
31
|
+
end
|
|
32
|
+
super
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -3,26 +3,33 @@
|
|
|
3
3
|
# rbs_inline: enabled
|
|
4
4
|
|
|
5
5
|
module RubyModKit
|
|
6
|
-
|
|
6
|
+
module Memo
|
|
7
7
|
# The memo for parameter type
|
|
8
|
-
class
|
|
8
|
+
class IvarMemo
|
|
9
9
|
# @rbs @type: nil | String
|
|
10
10
|
# @rbs @attr_kind: nil | Symbol
|
|
11
|
+
# @rbs @offset: nil | Integer
|
|
12
|
+
# @rbs @indent: String
|
|
11
13
|
# @rbs @name: Symbol
|
|
14
|
+
# @rbs @visibility: nil | Symbol
|
|
12
15
|
|
|
13
16
|
attr_reader :type #: nil | String
|
|
14
17
|
attr_reader :attr_kind #: nil | Symbol
|
|
18
|
+
attr_accessor :offset #: nil | Integer
|
|
19
|
+
attr_accessor :indent #: String
|
|
20
|
+
attr_accessor :visibility #: nil | Symbol
|
|
15
21
|
|
|
16
22
|
# @rbs name: Symbol
|
|
17
23
|
# @rbs return: void
|
|
18
24
|
def initialize(name)
|
|
19
25
|
@name = name
|
|
26
|
+
@indent = ""
|
|
20
27
|
end
|
|
21
28
|
|
|
22
29
|
# @rbs type: String
|
|
23
30
|
# @rbs return: void
|
|
24
31
|
def type=(type)
|
|
25
|
-
@type =
|
|
32
|
+
@type = RubyModKit.unify_type(type)
|
|
26
33
|
end
|
|
27
34
|
|
|
28
35
|
# @rbs kind: Symbol | String
|
|
@@ -37,6 +44,15 @@ module RubyModKit
|
|
|
37
44
|
@attr_kind = :attr_accessor
|
|
38
45
|
end
|
|
39
46
|
end
|
|
47
|
+
|
|
48
|
+
# @rbs offset_diff: OffsetDiff
|
|
49
|
+
# @rbs return: void
|
|
50
|
+
def succ(offset_diff)
|
|
51
|
+
offset = @offset
|
|
52
|
+
return unless offset
|
|
53
|
+
|
|
54
|
+
@offset = offset_diff[offset]
|
|
55
|
+
end
|
|
40
56
|
end
|
|
41
57
|
end
|
|
42
58
|
end
|