orthoses 0.2.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +61 -0
  3. data/README.md +16 -0
  4. data/examples/minitest/Rakefile +56 -0
  5. data/examples/simple_middleware.rb +11 -0
  6. data/examples/simple_middleware.rbs +7 -0
  7. data/lib/orthoses/attribute.rb +98 -0
  8. data/lib/orthoses/avoid_recursive_ancestor_error.rb +22 -0
  9. data/lib/orthoses/builder.rb +1 -0
  10. data/lib/orthoses/call_tracer.rb +3 -2
  11. data/lib/orthoses/content/duplication_checker.rb +30 -12
  12. data/lib/orthoses/content/environment.rb +106 -0
  13. data/lib/orthoses/content/header_builder.rb +94 -0
  14. data/lib/orthoses/content.rb +56 -29
  15. data/lib/orthoses/create_file_by_name.rb +7 -1
  16. data/lib/orthoses/delegate_class.rb +0 -1
  17. data/lib/orthoses/load_rbs.rb +2 -72
  18. data/lib/orthoses/mixin.rb +1 -9
  19. data/lib/orthoses/rbs_prototype_rb.rb +37 -0
  20. data/lib/orthoses/utils.rb +14 -7
  21. data/lib/orthoses/version.rb +1 -1
  22. data/lib/orthoses/writer.rb +16 -0
  23. data/lib/orthoses.rb +4 -0
  24. data/sig/orthoses/attribute/hook.rbs +4 -0
  25. data/sig/orthoses/attribute.rbs +4 -0
  26. data/sig/orthoses/avoid_recursive_ancestor_error.rbs +7 -0
  27. data/sig/orthoses/call_tracer.rbs +1 -0
  28. data/sig/orthoses/const_load_error.rbs +1 -1
  29. data/sig/orthoses/content/environment.rbs +13 -0
  30. data/sig/orthoses/content/header_builder.rbs +4 -0
  31. data/sig/orthoses/content.rbs +3 -0
  32. data/sig/orthoses/delegate_class.rbs +3 -0
  33. data/sig/orthoses/load_rbs.rbs +4 -0
  34. data/sig/orthoses/name_space_error.rbs +1 -1
  35. data/sig/orthoses/object_space_all.rbs +3 -0
  36. data/sig/orthoses/rbs_prototype_rb.rbs +10 -0
  37. data/sig/orthoses/tap.rbs +3 -0
  38. data/sig/orthoses/utils.rbs +2 -2
  39. data/sig/orthoses/writer.rbs +7 -0
  40. data/sig/orthoses.rbs +2 -2
  41. metadata +20 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c2fbbb509545bf6efd770838fff4ac02168f0352f0f2e2561ed927eb3479a4bb
4
- data.tar.gz: 259b1cf53cc3b2ea17ec3d6088260131ccd9d8562ec002b0d515cb817b96d228
3
+ metadata.gz: db149183688863139dfc513f92a150464497d1df409c495377817b4d3671db00
4
+ data.tar.gz: a02eb903127a7f6daf17750b9263ffee63a880b381ccfc47e76aa82e52252af3
5
5
  SHA512:
6
- metadata.gz: 50aceef69e828e6fbd90cbb23813bd66676b399d4a5551728eebf9ae8c24544aeda11c7d57810826575c53b215da541d232eb5a8ecb26fb9cf2d5a99822c7a91
7
- data.tar.gz: 36972f90ecdf75efa516c2fb576ea616f2b949a5930463f01ff9046335ae6571d7e98f9c33593bee21397cd29754da4abdfea038c956eaaa74d92deded56ba71
6
+ metadata.gz: 0ada92bd790f9ff1fd4b4e1293c1d4dad77c08c3c2e39f4513655ce910db7239e2a9e34373395e5abb4025d341c3596ef48b5dd46c05312cf6e2e8ec92152558
7
+ data.tar.gz: cb126e961ab83cc8ce683aa852279bac3a8cd166d73cd9f28f9e13cb482f8949d4b2f48928d617c2e4804b558160aea2feb6b91e66d91bfc0de86822869ba030
data/Gemfile.lock ADDED
@@ -0,0 +1,61 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ orthoses (0.5.0)
5
+ rbs (~> 2.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activesupport (7.0.3)
11
+ concurrent-ruby (~> 1.0, >= 1.0.2)
12
+ i18n (>= 1.6, < 2)
13
+ minitest (>= 5.1)
14
+ tzinfo (~> 2.0)
15
+ ast (2.4.2)
16
+ concurrent-ruby (1.1.10)
17
+ ffi (1.15.5)
18
+ i18n (1.10.0)
19
+ concurrent-ruby (~> 1.0)
20
+ language_server-protocol (3.16.0.3)
21
+ listen (3.7.1)
22
+ rb-fsevent (~> 0.10, >= 0.10.3)
23
+ rb-inotify (~> 0.9, >= 0.9.10)
24
+ minitest (5.15.0)
25
+ parallel (1.22.1)
26
+ parser (3.1.2.0)
27
+ ast (~> 2.4.1)
28
+ rainbow (3.1.1)
29
+ rake (13.0.6)
30
+ rb-fsevent (0.11.1)
31
+ rb-inotify (0.10.1)
32
+ ffi (~> 1.0)
33
+ rbs (2.5.0)
34
+ rgot (1.1.0)
35
+ steep (1.0.0)
36
+ activesupport (>= 5.1)
37
+ language_server-protocol (>= 3.15, < 4.0)
38
+ listen (~> 3.0)
39
+ parallel (>= 1.0.0)
40
+ parser (>= 3.0)
41
+ rainbow (>= 2.2.2, < 4.0)
42
+ rbs (>= 2.3.2)
43
+ terminal-table (>= 2, < 4)
44
+ terminal-table (3.0.2)
45
+ unicode-display_width (>= 1.1.1, < 3)
46
+ tzinfo (2.0.4)
47
+ concurrent-ruby (~> 1.0)
48
+ unicode-display_width (2.1.0)
49
+
50
+ PLATFORMS
51
+ ruby
52
+
53
+ DEPENDENCIES
54
+ activesupport
55
+ orthoses!
56
+ rake (~> 13.0)
57
+ rgot (~> 1.1)
58
+ steep
59
+
60
+ BUNDLED WITH
61
+ 2.3.9
data/README.md CHANGED
@@ -103,6 +103,22 @@ class Tempfile < File
103
103
  end
104
104
  ```
105
105
 
106
+ ### Orthoses::Writer
107
+
108
+ Write output RBS to `io` option object.
109
+ `io` should be able to call `#write` method.
110
+ This is useful when you want to combine outputs into a single output.
111
+
112
+ ### Orthoses::RBSPrototypeRB
113
+
114
+ Run `rbs prototype rb` command process to `paths` option files.
115
+ `content_filter` option could filter with content decl.
116
+ `mixin_filter` option could filter with mixin(include, extend, prepend) decl.
117
+
118
+ ### Orthoses::AvoidRecursiveAncestorError
119
+
120
+ Mixin a module into an Object class raises `RBS::RecursiveAncestorError` when validation.
121
+ Please add this middleware then.
106
122
 
107
123
  ## Development
108
124
 
@@ -0,0 +1,56 @@
1
+ file :src do
2
+ sh "git clone https://github.com/minitest/minitest.git src"
3
+ end
4
+
5
+ desc "generate minitest"
6
+ task :minitest => :src do
7
+ $:.unshift(File.expand_path("src/lib"))
8
+
9
+ out = Pathname('out')
10
+ out.rmtree rescue nil
11
+ require 'orthoses'
12
+
13
+ Orthoses::Builder.new do
14
+ use Orthoses::CreateFileByName,
15
+ base_dir: out.to_s
16
+ use Orthoses::Filter, if: ->(name, content) {
17
+ name.start_with?("Minitest") || name == "Kernel"
18
+ }
19
+ use Orthoses::Constant,
20
+ strict: false,
21
+ if: ->(current, const, val, rbs){
22
+ !Orthoses::Utils.rbs_defined_const?("#{current}::#{const}")
23
+ }
24
+ use Orthoses::Mixin
25
+ use Orthoses::Attribute
26
+ use Orthoses::RBSPrototypeRB,
27
+ paths: Dir.glob('src/lib/minitest{.rb,/*.rb}'),
28
+ constant_filter: ->(_) { false },
29
+ mixin_filter: ->(_) { false },
30
+ attribute_filter: ->(_) { false }
31
+ run ->(){
32
+ require_relative 'src/lib/minitest'
33
+ require_relative 'src/lib/minitest/test'
34
+ require_relative 'src/lib/minitest/spec'
35
+ require_relative 'src/lib/minitest/parallel'
36
+ require_relative 'src/lib/minitest/mock'
37
+ require_relative 'src/lib/minitest/benchmark'
38
+
39
+ require_relative 'src/lib/minitest/pride_plugin'
40
+ }
41
+ end.call
42
+
43
+ sh "rbs -r mutex_m -I #{out} validate --silent"
44
+ out.join("manifest.yaml").write <<~YAML
45
+ dependencies:
46
+ - name: mutex_m
47
+ YAML
48
+ tmp = out.join("kernel.rbs").read
49
+ out.join("kernel.rbs").open("w") do |f|
50
+ f.puts "%a{annotate:rdoc:skip}"
51
+ f.write tmp
52
+ end
53
+ sh "rbs annotate --gems out"
54
+ end
55
+
56
+ task default: :minitest
@@ -0,0 +1,11 @@
1
+ module Orthoses
2
+ class Simple
3
+ def initialize(loader)
4
+ @loader = loader
5
+ end
6
+
7
+ def call
8
+ @loader.call
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ module Orthoses
2
+ class Simple
3
+ @loader: Orthoses::_Call
4
+ include Orthoses::_MiddleWare
5
+ def initialize: (Orthoses::_Call loader) -> void
6
+ end
7
+ end
@@ -0,0 +1,98 @@
1
+ module Orthoses
2
+ class Attribute
3
+ module Hook
4
+ def attr(*names)
5
+ super
6
+ end
7
+
8
+ def attr_accessor(*names)
9
+ super
10
+ end
11
+
12
+ def attr_reader(*names)
13
+ super
14
+ end
15
+
16
+ def attr_writer(*names)
17
+ super
18
+ end
19
+ end
20
+
21
+ def initialize(loader)
22
+ @loader = loader
23
+ end
24
+
25
+ def call
26
+ Module.prepend(Hook)
27
+
28
+ attr = CallTracer.new
29
+ attr_accessor = CallTracer.new
30
+ attr_reader = CallTracer.new
31
+ attr_writer = CallTracer.new
32
+
33
+ store = attr.trace(Hook.method(:attr)) do
34
+ attr_accessor.trace(Hook.method(:attr_accessor)) do
35
+ attr_reader.trace(Hook.method(:attr_reader)) do
36
+ attr_writer.trace(Hook.method(:attr_writer)) do
37
+ @loader.call
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ store["Module"].body.delete("prepend Orthoses::Attribute::Hook")
44
+
45
+ attr.result.each do |method, argument|
46
+ m = method.receiver.to_s.match(/#<Class:([\w:]+)>/)
47
+ if m && m[1]
48
+ receiver_name = m[1]
49
+ prefix = "self."
50
+ else
51
+ receiver_name = Utils.module_name(method.receiver) or next
52
+ prefix = nil
53
+ end
54
+ content = store[receiver_name]
55
+ if argument[:names][1].equal?(true)
56
+ content << "attr_accessor #{prefix}#{argument[:names][0]}: untyped"
57
+ elsif argument[:names][1].equal?(false)
58
+ content << "attr_reader #{prefix}#{argument[:names][0]}: untyped"
59
+ else
60
+ argument[:names].each do |name|
61
+ content << "attr_reader #{prefix}#{name}: untyped"
62
+ end
63
+ end
64
+ end
65
+
66
+ each_definition(attr_accessor) do |receiver_name, name|
67
+ store[receiver_name] << "attr_accessor #{name}: untyped"
68
+ end
69
+ each_definition(attr_reader) do |receiver_name, name|
70
+ store[receiver_name] << "attr_reader #{name}: untyped"
71
+ end
72
+ each_definition(attr_writer) do |receiver_name, name|
73
+ store[receiver_name] << "attr_writer #{name}: untyped"
74
+ end
75
+
76
+ store
77
+ end
78
+
79
+ private
80
+
81
+ def each_definition(call_tracer)
82
+ call_tracer.result.each do |method, argument|
83
+ m = method.receiver.to_s.match(/#<Class:([\w:]+)>/)
84
+ if m && m[1]
85
+ receiver_name = m[1]
86
+ argument[:names].each do |name|
87
+ yield [receiver_name, "self.#{name}"]
88
+ end
89
+ else
90
+ receiver_name = Utils.module_name(method.receiver) or next
91
+ argument[:names].each do |name|
92
+ yield [receiver_name, name]
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,22 @@
1
+ module Orthoses
2
+ class AvoidRecursiveAncestorError
3
+ def initialize(loader)
4
+ @loader = loader
5
+ end
6
+
7
+ def call
8
+ @loader.call.tap do |store|
9
+ object_mixins = {}
10
+ store["Object"].to_decl.members.each do |member|
11
+ case member
12
+ when RBS::AST::Members::Mixin
13
+ object_mixins[member.name.relative!.to_s] = true
14
+ end
15
+ end
16
+ object_mixins.each_key do |object_mixin|
17
+ store[object_mixin].header = "module #{object_mixin} : BasicObject"
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -27,6 +27,7 @@ module Orthoses
27
27
  end
28
28
 
29
29
  def use(middleware, *args, **key, &block)
30
+ Orthoses.logger.debug("use #{middleware}")
30
31
  @use << proc do |loader|
31
32
  middleware.new(loader, *args, **key, &block).tap do |m|
32
33
  m.extend CallLogable
@@ -20,7 +20,7 @@ module Orthoses
20
20
  end
21
21
 
22
22
  def trace(target, &block)
23
- TracePoint.new(:call) do |tp|
23
+ t = TracePoint.new(:call) do |tp|
24
24
  called_method = tp.self.method(tp.method_id)
25
25
  argument = tp.parameters.each_with_object({}) do |op_name, hash|
26
26
  name = op_name[1]
@@ -47,7 +47,8 @@ module Orthoses
47
47
  end
48
48
  end
49
49
  @result << [called_method, argument]
50
- end.enable(target: target, &block)
50
+ end
51
+ t.enable(target: target, &block)
51
52
  end
52
53
  end
53
54
  end
@@ -4,24 +4,35 @@ module Orthoses
4
4
  class DuplicationChecker
5
5
  def initialize(decl)
6
6
  @decl = decl
7
- @uniq_map = {}
8
7
  end
9
8
 
10
- def <<(member)
11
- key = member_key(member)
12
- if @uniq_map.key?(key)
13
- Orthoses.logger.warn("#{@decl.name}::#{member_to_s(member)} was droped since duplication")
14
- else
15
- @uniq_map[key] = member
9
+ def update_decl
10
+ uniq_map = {}
11
+ @decl.members.each do |member|
12
+ key = member_key(member)
13
+ drop_member = uniq_map[key]
14
+ uniq_map[key] = member
15
+ if drop_member
16
+ Orthoses.logger.warn("#{@decl.name}::#{drop_member} was droped since duplication")
17
+ end
16
18
  end
17
- end
18
-
19
- def uniq_members
20
- @uniq_map.values
19
+ drop_known_method_definition(uniq_map)
20
+ @decl.members.replace(uniq_map.values)
21
21
  end
22
22
 
23
23
  private
24
24
 
25
+ def drop_known_method_definition(uniq_map)
26
+ env = Utils.rbs_environment(collection: true)
27
+ if m_entry = env.class_decls[@decl.name.absolute!]
28
+ m_entry.decls.each do |d|
29
+ d.decl.members.grep_v(RBS::AST::Members::LocationOnly).each do |member|
30
+ uniq_map.delete(member_key(member))
31
+ end
32
+ end
33
+ end
34
+ end
35
+
25
36
  def member_to_s(member)
26
37
  out = StringIO.new
27
38
  RBS::Writer.new(out: out).write_member(member)
@@ -36,7 +47,14 @@ module Orthoses
36
47
  when RBS::AST::Members::LocationOnly
37
48
  [member.class]
38
49
  when RBS::AST::Members::Alias
39
- [member.class, member.new_name, member.old_name, member.kind]
50
+ [RBS::AST::Members::MethodDefinition, member.new_name, member.kind]
51
+ when RBS::AST::Members::AttrAccessor
52
+ # FIXME: how to check "#{member.name}=" ?
53
+ [RBS::AST::Members::MethodDefinition, member.name, member.kind]
54
+ when RBS::AST::Members::AttrReader
55
+ [RBS::AST::Members::MethodDefinition, member.name, member.kind]
56
+ when RBS::AST::Members::AttrWriter
57
+ [RBS::AST::Members::MethodDefinition, "#{member.name}=", member.kind]
40
58
  else
41
59
  [member.class, member.name]
42
60
  end
@@ -0,0 +1,106 @@
1
+ module Orthoses
2
+ class Content
3
+ class Environment
4
+ class << self
5
+ def load_from_paths(paths)
6
+ new.tap do |env|
7
+ paths.each do |path|
8
+ Orthoses.logger.debug("Load #{path}")
9
+ buffer = RBS::Buffer.new(name: path.to_s, content: File.read(path.to_s, encoding: "UTF-8"))
10
+ RBS::Parser.parse_signature(buffer).each do |decl|
11
+ env << decl
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+
18
+ def initialize(constant_filter: nil, mixin_filter: nil, attribute_filter: nil)
19
+ @load_env = RBS::Environment.new
20
+ @known_env = Utils.rbs_environment(collection: true, cache: false)
21
+ @constant_filter = constant_filter
22
+ @mixin_filter = mixin_filter
23
+ @attribute_filter = attribute_filter
24
+ end
25
+
26
+ def <<(decl)
27
+ @load_env << decl
28
+ @known_env << decl
29
+ rescue RBS::DuplicatedDeclarationError => err
30
+ Orthoses.logger.warn(err.inspect)
31
+ end
32
+
33
+ def write_to(store:)
34
+ each do |add_content|
35
+ content = store[add_content.name]
36
+ content.header = add_content.header
37
+ content.concat(add_content.body)
38
+ end
39
+ end
40
+
41
+ def each
42
+ avoid_generic_parameter_mismatch_error
43
+
44
+ header_builder = HeaderBuilder.new(env: @known_env)
45
+
46
+ @load_env.class_decls.each do |type_name, m_entry|
47
+ name = type_name.relative!.to_s
48
+ content = Content.new(name: name)
49
+ content.header = header_builder.build(entry: m_entry, name_hint: name)
50
+ decls_to_lines(m_entry.decls.map(&:decl)).each do |line|
51
+ content << line
52
+ end
53
+ yield content
54
+ end
55
+
56
+ @load_env.interface_decls.each do |type_name, s_entry|
57
+ name = type_name.relative!.to_s
58
+ content = Content.new(name: name)
59
+ content.header = header_builder.build(entry: s_entry)
60
+ decls_to_lines([s_entry.decl]).each do |line|
61
+ content << line
62
+ end
63
+ yield content
64
+ end
65
+ end
66
+
67
+ private
68
+
69
+ # Avoid `RBS::GenericParameterMismatchError` from like rbs_prototype_rb
70
+ # class Array # <= RBS::GenericParameterMismatchError
71
+ # end
72
+ def avoid_generic_parameter_mismatch_error
73
+ @known_env.class_decls.each do |type_name, m_entry|
74
+ tmp_primary_d = m_entry.decls.find { |d| !d.decl.type_params.empty? }
75
+ next unless tmp_primary_d
76
+ m_entry.decls.each do |d|
77
+ if d.decl.type_params.empty?
78
+ d.decl.type_params.replace(tmp_primary_d.decl.type_params)
79
+ end
80
+ end
81
+ end
82
+ end
83
+
84
+ def decls_to_lines(decls)
85
+ out = StringIO.new
86
+ writer = RBS::Writer.new(out: out)
87
+ decls.each do |decl|
88
+ next unless decl.respond_to?(:members)
89
+ decl.members.each do |member|
90
+ next if member.respond_to?(:members)
91
+ case member
92
+ when RBS::AST::Declarations::Constant
93
+ next unless @constant_filter.nil? || @constant_filter.call(member)
94
+ when RBS::AST::Members::Mixin
95
+ next unless @mixin_filter.nil? || @mixin_filter.call(member)
96
+ when RBS::AST::Members::Attribute
97
+ next unless @attribute_filter.nil? || @attribute_filter.call(member)
98
+ end
99
+ writer.write_member(member)
100
+ end
101
+ end
102
+ out.string.each_line(chomp: true).to_a
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,94 @@
1
+ module Orthoses
2
+ class Content
3
+ class HeaderBuilder
4
+ def initialize(env:)
5
+ @env = env
6
+ @resolver = RBS::TypeNameResolver.from_env(env)
7
+ end
8
+
9
+ def build(entry:, name_hint: nil)
10
+ case entry
11
+ when RBS::Environment::ModuleEntry
12
+ build_module(entry: entry, name_hint: name_hint)
13
+ when RBS::Environment::ClassEntry
14
+ build_class(entry: entry, name_hint: name_hint)
15
+ when RBS::Environment::SingleEntry
16
+ build_interface(entry: entry, name_hint: name_hint)
17
+ else
18
+ raise
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def build_module(entry:, name_hint: nil)
25
+ primary = entry.primary
26
+ full_name = name_hint || primary.decl.name.relative!
27
+
28
+ self_types =
29
+ if primary.decl.self_types.empty?
30
+ nil
31
+ else
32
+ " : #{primary.decl.self_types.join(', ')}"
33
+ end
34
+
35
+ "module #{name_and_params(full_name, primary.decl.type_params)}#{self_types}"
36
+ end
37
+
38
+ def build_class(entry:, name_hint: nil)
39
+ primary = entry.primary
40
+ full_name = name_hint || primary.decl.name.relative!
41
+
42
+ "class #{name_and_params(full_name, primary.decl.type_params)}#{build_super_class(primary)}"
43
+ end
44
+
45
+ def build_super_class(primary)
46
+ return nil if primary.decl.super_class.then { |s| s.nil? || s.name.relative!.to_s.then { |n| n == "Object" || n == "Random::Base" } }
47
+
48
+ context = primary.outer.length.times.map do |i|
49
+ primary.outer[0, i + 1].map(&:name).inject(:+).to_namespace.absolute!
50
+ end
51
+ context.push(RBS::Namespace.root)
52
+
53
+ super_class_name = @resolver.resolve(primary.decl.super_class.name, context: context) || primary.decl.super_class.name
54
+ if primary.decl.super_class.args.empty?
55
+ if super_class_entry = @env.class_decls[super_class_name]
56
+ super_primary = super_class_entry.primary
57
+ " < #{name_and_args(super_class_name, super_primary.decl.type_params.map { :untyped })}"
58
+ else
59
+ " < #{name_and_args(super_class_name, [])}"
60
+ end
61
+ else
62
+ " < #{name_and_args(super_class_name, primary.decl.super_class.args)}"
63
+ end
64
+ end
65
+
66
+ def build_interface(entry:, name_hint: nil)
67
+ full_name = name_hint || entry.decl.name.relative!
68
+ "interface #{name_and_params(full_name, entry.decl.type_params)}"
69
+ end
70
+
71
+ def name_and_params(name, params)
72
+ if params.empty?
73
+ "#{name}"
74
+ else
75
+ ps = params.each.map do |param|
76
+ param.to_s
77
+ end
78
+
79
+ "#{name}[#{ps.join(", ")}]"
80
+ end
81
+ end
82
+
83
+ def name_and_args(name, args)
84
+ if name && args
85
+ if args.empty?
86
+ "#{name}"
87
+ else
88
+ "#{name}[#{args.join(", ")}]"
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'orthoses/content/duplication_checker'
4
+ require 'orthoses/content/environment'
5
+ require 'orthoses/content/header_builder'
4
6
 
5
7
  module Orthoses
6
8
  # Common interface for output.
@@ -19,31 +21,79 @@ module Orthoses
19
21
  attr_accessor :header
20
22
 
21
23
  def initialize(name:)
24
+ Orthoses.logger.debug("Create Orthoses::Content for #{name}")
22
25
  @name = name
23
26
  @body = []
24
27
  @header = nil
25
28
  end
26
29
 
27
30
  def <<(line)
28
- Orthoses.logger.debug("[#{name}] << #{line} on #{__FILE__}:#{__LINE__}")
29
31
  @body << line
30
32
  end
31
33
 
32
34
  def concat(other)
33
- Orthoses.logger.debug("[#{name}] concat #{other} on #{__FILE__}:#{__LINE__}")
34
35
  @body.concat(other)
35
36
  end
36
37
 
37
38
  def to_rbs
38
- if @header.nil?
39
- auto_header
40
- end
41
- body_uniq("#{@header}\n#{@body.map { |b| " #{b}\n" }.join}end\n")
39
+ auto_header
40
+ uniqed_body_string
41
+ end
42
+
43
+ def to_decl
44
+ auto_header
45
+ uniqed_body_decl
42
46
  end
43
47
 
44
48
  private
45
49
 
50
+ def original_rbs
51
+ <<~RBS
52
+ #{@header}
53
+ #{@body.join("\n")}
54
+ end
55
+ RBS
56
+ end
57
+
58
+ def uniqed_body_string
59
+ out = StringIO.new
60
+ writer = RBS::Writer.new(out: out)
61
+ writer.write_decl(uniqed_body_decl)
62
+ out.string
63
+ end
64
+
65
+ def uniqed_body_decl
66
+ buffer = RBS::Buffer.new(
67
+ name: "orthoses/content.rb",
68
+ content: original_rbs
69
+ )
70
+ parsed_decls = RBS::Parser.parse_signature(buffer)
71
+ unless parsed_decls.length == 1
72
+ raise "expect decls.length == 1, but got #{parsed_decls.length}"
73
+ end
74
+ parsed_decl = parsed_decls.first or raise
75
+ parsed_decl.tap do |decl|
76
+ DuplicationChecker.new(decl).update_decl
77
+ end
78
+ rescue RBS::ParsingError
79
+ Orthoses.logger.error "```rbs\n#{original_rbs}```"
80
+ raise
81
+ end
82
+
46
83
  def auto_header
84
+ if name.split('::').last.start_with?('_')
85
+ self.header = "interface #{name}"
86
+ return
87
+ end
88
+
89
+ env = Utils.rbs_environment(collection: true)
90
+ if entry = env.class_decls[TypeName(name).absolute!]
91
+ @header = Content::HeaderBuilder.new(env: env).build(entry: entry)
92
+ return
93
+ end
94
+
95
+ return unless @header.nil?
96
+
47
97
  val = Object.const_get(name)
48
98
 
49
99
  case val
@@ -87,28 +137,5 @@ module Orthoses
87
137
  end
88
138
  end
89
139
  end
90
-
91
- def body_uniq(rbs)
92
- buffer = RBS::Buffer.new(
93
- name: "orthoses/content.rb",
94
- content: rbs
95
- )
96
- out = StringIO.new
97
- writer = RBS::Writer.new(out: out)
98
- decls = RBS::Parser.parse_signature(buffer).map do |parsed_decl|
99
- parsed_decl.tap do |decl|
100
- duplicate_checker = DuplicationChecker.new(decl)
101
- decl.members.each do |member|
102
- duplicate_checker << member
103
- end
104
- decl.members.replace(duplicate_checker.uniq_members)
105
- end
106
- end
107
- writer.write(decls)
108
- out.string
109
- rescue RBS::ParsingError
110
- Orthoses.logger.error "```rbs\n#{rbs}```"
111
- raise
112
- end
113
140
  end
114
141
  end
@@ -28,6 +28,12 @@ module Orthoses
28
28
  store = @loader.call
29
29
 
30
30
  store.each do |name, content|
31
+ rbs = begin
32
+ content.to_rbs
33
+ rescue NameError, LoadError => err
34
+ Orthoses.logger.error(err.inspect)
35
+ next
36
+ end
31
37
  file_path = Pathname("#{@base_dir}/#{name.to_s.split('::').map(&:underscore).join('/')}.rbs")
32
38
  file_path.dirname.mkpath
33
39
  file_path.open('w+') do |out|
@@ -35,7 +41,7 @@ module Orthoses
35
41
  out.puts @header
36
42
  out.puts
37
43
  end
38
- out.puts content.to_rbs
44
+ out.puts rbs
39
45
  end
40
46
  Orthoses.logger.info("Generate file to #{file_path.to_s}")
41
47
  end
@@ -29,7 +29,6 @@ module Orthoses
29
29
  next unless subclass_name
30
30
  delegate_to_class_name = Utils.module_name(delegate_to_class)
31
31
  next unless delegate_to_class_name
32
- next unless store[subclass_name].header.nil?
33
32
 
34
33
  header = "class #{subclass_name} < ::#{delegate_to_class_name}#{temporary_type_params(delegate_to_class_name)}"
35
34
  store[subclass_name].header = header
@@ -11,79 +11,9 @@ module Orthoses
11
11
 
12
12
  def call
13
13
  @loader.call.tap do |store|
14
- tmp_env = RBS::Environment.new
15
-
16
- @paths.each do |path|
17
- Orthoses.logger.debug("Load #{path}")
18
- buffer = RBS::Buffer.new(name: path.to_s, content: File.read(path.to_s, encoding: "UTF-8"))
19
- decls = RBS::Parser.parse_signature(buffer)
20
- decls.each { |decl| tmp_env << decl }
21
- end
22
-
23
- tmp_env.class_decls.each do |type_name, m_entry|
24
- name = type_name.relative!.to_s
25
- content = store[name]
26
- case decl = m_entry.decls.first.decl
27
- when RBS::AST::Declarations::Module
28
- self_types = decl.self_types.empty? ? nil : " : #{decl.self_types.join(', ')}"
29
- content.header = "module #{name_and_params(name, decl.type_params)}#{self_types}"
30
- when RBS::AST::Declarations::Class
31
- super_class = decl.super_class.nil? ? nil : " < #{name_and_args(decl.super_class.name, decl.super_class.args)}"
32
- content.header = "class #{name_and_params(name, decl.type_params)}#{super_class}"
33
- end
34
- decls_to_lines(m_entry.decls.map(&:decl)).each do |line|
35
- content << line
36
- end
37
- end
38
-
39
- tmp_env.interface_decls.each do |type_name, s_entry|
40
- name = type_name.relative!.to_s
41
- content = store[name]
42
- decl = s_entry.decl
43
- content.header = "interface #{name_and_params(name, decl.type_params)}"
44
- decls_to_lines([decl]).each do |line|
45
- content << line
46
- end
47
- end
48
- end
49
- end
50
-
51
- private
52
-
53
- def name_and_params(name, params)
54
- if params.empty?
55
- "#{name}"
56
- else
57
- ps = params.each.map do |param|
58
- param.to_s
59
- end
60
-
61
- "#{name}[#{ps.join(", ")}]"
62
- end
63
- end
64
-
65
- def name_and_args(name, args)
66
- if name && args
67
- if args.empty?
68
- "#{name}"
69
- else
70
- "#{name}[#{args.join(", ")}]"
71
- end
72
- end
73
- end
74
-
75
- def decls_to_lines(decls)
76
- out = StringIO.new
77
- writer = RBS::Writer.new(out: out)
78
- decls.each do |decl|
79
- if decl.respond_to?(:members)
80
- decl.members.each do |member|
81
- next if member.respond_to?(:members)
82
- writer.write_member(member)
83
- end
84
- end
14
+ env = Content::Environment.load_from_paths(@paths)
15
+ env.write_to(store: store)
85
16
  end
86
- out.string.each_line(chomp: true).to_a
87
17
  end
88
18
  end
89
19
  end
@@ -37,15 +37,7 @@ module Orthoses
37
37
  next unless known_type_params.nil? || known_type_params.empty?
38
38
  next unless @if.nil? || @if.call(base_mod, how, mod)
39
39
 
40
- if base_mod_name == "Object"
41
- # avoid RecursiveAncestorError
42
- content = store[mod_name]
43
- if content.header.nil?
44
- content.header = "module #{Utils.module_to_type_name(mod)} : ::BasicObject"
45
- end
46
- else
47
- store[mod_name]
48
- end
40
+ store[mod_name]
49
41
 
50
42
  "#{how} #{mod_name}"
51
43
  end
@@ -0,0 +1,37 @@
1
+ module Orthoses
2
+ # Call `rbs prototype rb` and add to store
3
+ # use Orthoses::RBSPrototypeRB,
4
+ # paths: Dir.glob("lib/**/*.rb")
5
+ class RBSPrototypeRB
6
+ def initialize(loader, paths:, constant_filter: nil, mixin_filter: nil, attribute_filter: nil)
7
+ @loader = loader
8
+ @paths = paths
9
+ @constant_filter = constant_filter
10
+ @mixin_filter = mixin_filter
11
+ @attribute_filter = attribute_filter
12
+ end
13
+
14
+ def call
15
+ @loader.call.tap do |store|
16
+ parser = RBS::Prototype::RB.new
17
+ @paths.each do |path|
18
+ begin
19
+ Orthoses.logger.debug("parse #{path} by RBS::Prototype::RB")
20
+ parser.parse File.read(path.to_s)
21
+ rescue => err
22
+ Orthoses.logger.error("Parse error #{err.inspect} by RBS::Prototype::RB #{path}")
23
+ end
24
+ end
25
+ env = Orthoses::Content::Environment.new(
26
+ constant_filter: @constant_filter,
27
+ mixin_filter: @mixin_filter,
28
+ attribute_filter: @attribute_filter,
29
+ )
30
+ parser.decls.each do |decl|
31
+ env << decl
32
+ end
33
+ env.write_to(store: store)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -46,9 +46,9 @@ module Orthoses
46
46
  RBS::Namespace.parse(name).to_type_name
47
47
  end
48
48
 
49
- def self.rbs_environment(library: nil, collection: false)
49
+ def self.rbs_environment(library: nil, collection: false, cache: true)
50
50
  @env_cache ||= {}
51
- if hit = @env_cache[[library, collection]]
51
+ if cache && hit = @env_cache[[library, collection]]
52
52
  return hit
53
53
  end
54
54
 
@@ -63,16 +63,17 @@ module Orthoses
63
63
  when "stdlib"
64
64
  RBS::Repository::DEFAULT_STDLIB_ROOT.each_entry do |path|
65
65
  lib = path.to_s
66
- loader.add(library: lib.to_s) unless lib == "." || lib == ".."
66
+ loader.add(library: lib.to_s, version: nil) unless lib == "." || lib == ".."
67
67
  end
68
68
  else
69
69
  Array(library).each do |lib|
70
- loader.add(library: lib.to_s)
70
+ loader.add(library: lib.to_s, version: nil)
71
71
  end
72
72
  end
73
73
 
74
- environment = RBS::Environment.from_loader(loader).resolve_type_names
75
- @env_cache[[library, collection]] = environment
74
+ RBS::Environment.from_loader(loader).resolve_type_names.tap do |env|
75
+ @env_cache[[library, collection]] = env if cache
76
+ end
76
77
  end
77
78
 
78
79
  def self.object_to_rbs(object, strict:)
@@ -117,10 +118,16 @@ module Orthoses
117
118
  "{ #{object.map { |k, v| "#{k}: #{object_to_rbs(v, strict: strict)}" }.join(', ')} }"
118
119
  else
119
120
  keys = object.keys.map { |k| object_to_rbs(k, strict: strict) }.uniq
120
- values = object.values.map { |k| object_to_rbs(k, strict: strict) }.uniq
121
+ values = object.values.map { |v| object_to_rbs(v, strict: strict) }.uniq
121
122
  "Hash[#{keys.join(' | ')}, #{values.join(' | ')}]"
122
123
  end
123
124
  end
125
+ when Range
126
+ type = object_to_rbs(object.begin || object.end, strict: false)
127
+ "Range[#{type}]"
128
+ when ARGF
129
+ # see also https://github.com/ruby/rbs/pull/975
130
+ 'untyped'
124
131
  else
125
132
  Utils.module_name(object.class) || 'untyped'
126
133
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Orthoses
4
- VERSION = "0.2.0"
4
+ VERSION = "0.5.0"
5
5
  end
@@ -0,0 +1,16 @@
1
+ module Orthoses
2
+ class Writer
3
+ def initialize(loader, io:)
4
+ @loader = loader
5
+ @io = io
6
+ end
7
+
8
+ def call
9
+ @loader.call.tap do |store|
10
+ store.each do |name, content|
11
+ @io.write content.to_rbs
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
data/lib/orthoses.rb CHANGED
@@ -3,6 +3,8 @@
3
3
  require 'rbs'
4
4
  require 'pathname'
5
5
 
6
+ require_relative 'orthoses/attribute'
7
+ require_relative 'orthoses/avoid_recursive_ancestor_error'
6
8
  require_relative 'orthoses/builder'
7
9
  require_relative 'orthoses/call_tracer'
8
10
  require_relative 'orthoses/constant'
@@ -14,11 +16,13 @@ require_relative 'orthoses/mixin'
14
16
  require_relative 'orthoses/load_rbs'
15
17
  require_relative 'orthoses/object_space_all'
16
18
  require_relative 'orthoses/pp'
19
+ require_relative 'orthoses/rbs_prototype_rb'
17
20
  require_relative 'orthoses/store'
18
21
  require_relative 'orthoses/tap'
19
22
  require_relative 'orthoses/utils'
20
23
  require_relative 'orthoses/version'
21
24
  require_relative 'orthoses/walk'
25
+ require_relative 'orthoses/writer'
22
26
 
23
27
  module Orthoses
24
28
  class ConstLoadError < StandardError
@@ -0,0 +1,4 @@
1
+ # THIS IS GENERATED CODE from `$ rake generate_self_sig`
2
+
3
+ module Orthoses::Attribute::Hook
4
+ end
@@ -0,0 +1,4 @@
1
+ # THIS IS GENERATED CODE from `$ rake generate_self_sig`
2
+
3
+ class Orthoses::Attribute
4
+ end
@@ -0,0 +1,7 @@
1
+ # THIS IS GENERATED CODE from `$ rake generate_self_sig`
2
+
3
+ class Orthoses::AvoidRecursiveAncestorError
4
+ @loader: Orthoses::_Call
5
+ include Orthoses::_MiddleWare
6
+ def initialize: (Orthoses::_Call loader) -> void
7
+ end
@@ -2,4 +2,5 @@
2
2
 
3
3
  class Orthoses::CallTracer
4
4
  attr_accessor result: Array[[ Method, Hash[Symbol, untyped] ]]
5
+ def trace: [T] (Method | UnboundMethod) ?{ () -> T } -> T
5
6
  end
@@ -1,6 +1,6 @@
1
1
  # THIS IS GENERATED CODE from `$ rake generate_self_sig`
2
2
 
3
- class Orthoses::ConstLoadError < StandardError
3
+ class Orthoses::ConstLoadError < ::StandardError
4
4
  attr_reader root: Module
5
5
  attr_reader const: Symbol
6
6
  attr_reader error: untyped
@@ -0,0 +1,13 @@
1
+ # THIS IS GENERATED CODE from `$ rake generate_self_sig`
2
+
3
+ class Orthoses::Content::Environment
4
+ type constant_filter = ^(RBS::AST::Declarations::Constant) -> boolish
5
+ type mixin_filter = ^(RBS::AST::Members::Mixin) -> boolish
6
+ @env: RBS::Environment
7
+ @constant_filter: constant_filter?
8
+ @mixin_filter: mixin_filter?
9
+ def initialize: (?constant_filter: constant_filter?, ?mixin_filter: mixin_filter?) -> void
10
+ def <<: (RBS::AST::Declarations::t decl) -> RBS::Environment
11
+ def write_to: (store: Orthoses::store) -> void
12
+ def each: () { (Orthoses::Content) -> void } -> void
13
+ end
@@ -0,0 +1,4 @@
1
+ # THIS IS GENERATED CODE from `$ rake generate_self_sig`
2
+
3
+ class Orthoses::Content::HeaderBuilder
4
+ end
@@ -8,4 +8,7 @@ class Orthoses::Content
8
8
  def <<: (String) -> void
9
9
  def concat: (Array[String]) -> void
10
10
  def to_rbs: () -> String
11
+ private
12
+ def uniqed_body_string: () -> String
13
+ def uniqed_body_decl: () -> RBS::AST::Declarations::t
11
14
  end
@@ -1,4 +1,7 @@
1
1
  # THIS IS GENERATED CODE from `$ rake generate_self_sig`
2
2
 
3
3
  class Orthoses::DelegateClass
4
+ @loader: Orthoses::_Call
5
+ include Orthoses::_MiddleWare
6
+ def initialize: (Orthoses::_Call loader) -> void
4
7
  end
@@ -1,4 +1,8 @@
1
1
  # THIS IS GENERATED CODE from `$ rake generate_self_sig`
2
2
 
3
3
  class Orthoses::LoadRBS
4
+ @loader: Orthoses::_Call
5
+ @paths: Array[_ToS]
6
+ include Orthoses::_MiddleWare
7
+ def initialize: (Orthoses::_Call loader, paths: Array[_ToS]) -> void
4
8
  end
@@ -1,4 +1,4 @@
1
1
  # THIS IS GENERATED CODE from `$ rake generate_self_sig`
2
2
 
3
- class Orthoses::NameSpaceError < StandardError
3
+ class Orthoses::NameSpaceError < ::StandardError
4
4
  end
@@ -1,4 +1,7 @@
1
1
  # THIS IS GENERATED CODE from `$ rake generate_self_sig`
2
2
 
3
3
  class Orthoses::ObjectSpaceAll
4
+ @loader: Orthoses::_Call
5
+ include Orthoses::_MiddleWare
6
+ def initialize: (Orthoses::_Call loader, ?if: ^(Module) -> boolish) -> void
4
7
  end
@@ -0,0 +1,10 @@
1
+ # THIS IS GENERATED CODE from `$ rake generate_self_sig`
2
+
3
+ class Orthoses::RBSPrototypeRB
4
+ @loader: Orthoses::_Call
5
+ include Orthoses::_MiddleWare
6
+ def initialize: (Orthoses::_Call loader, paths: Array[_ToS], ?constant_filter: Orthoses::Content::Environment::constant_filter?, ?mixin_filter: Orthoses::Content::Environment::mixin_filter?) -> void
7
+ @paths: Array[_ToS]
8
+ @constant_filter: Orthoses::Content::Environment::constant_filter?
9
+ @mixin_filter: Orthoses::Content::Environment::mixin_filter?
10
+ end
data/sig/orthoses/tap.rbs CHANGED
@@ -1,4 +1,7 @@
1
1
  # THIS IS GENERATED CODE from `$ rake generate_self_sig`
2
2
 
3
3
  class Orthoses::Tap
4
+ @loader: Orthoses::_Call
5
+ include Orthoses::_MiddleWare
6
+ def initialize: (Orthoses::_Call loader) -> void
4
7
  end
@@ -1,8 +1,6 @@
1
1
  # THIS IS GENERATED CODE from `$ rake generate_self_sig`
2
2
 
3
3
  module Orthoses::Utils
4
- UNBOUND_NAME_METHOD: UnboundMethod
5
-
6
4
  def self.unautoload!: () -> void
7
5
 
8
6
  def self.each_const_recursive: (Module root, ?cache: Hash[untyped, true], ?on_error: ^(Orthoses::ConstLoadError) -> void?) ?{ (Module, Symbol, untyped) -> void } -> void
@@ -24,4 +22,6 @@ module Orthoses::Utils
24
22
  def self.known_type_params: (Module | String) -> Array[RBS::AST::TypeParam]
25
23
 
26
24
  def self.new_store: () -> Orthoses::store
25
+
26
+ UNBOUND_NAME_METHOD: UnboundMethod
27
27
  end
@@ -0,0 +1,7 @@
1
+ # THIS IS GENERATED CODE from `$ rake generate_self_sig`
2
+
3
+ class Orthoses::Writer
4
+ @loader: Orthoses::_Call
5
+ include Orthoses::_MiddleWare
6
+ def initialize: (Orthoses::_Call loader, io: _Writer) -> void
7
+ end
data/sig/orthoses.rbs CHANGED
@@ -1,9 +1,9 @@
1
1
  # THIS IS GENERATED CODE from `$ rake generate_self_sig`
2
2
 
3
3
  module Orthoses
4
- VERSION: String
5
-
6
4
  attr_accessor self.logger: ::Logger
7
5
 
8
6
  type store = Hash[String, Orthoses::Content]
7
+
8
+ VERSION: "0.4.0"
9
9
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: orthoses
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ksss
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-05-09 00:00:00.000000000 Z
11
+ date: 2022-05-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rbs
@@ -33,14 +33,22 @@ extra_rdoc_files: []
33
33
  files:
34
34
  - CODE_OF_CONDUCT.md
35
35
  - Gemfile
36
+ - Gemfile.lock
36
37
  - LICENSE.txt
37
38
  - README.md
39
+ - examples/minitest/Rakefile
40
+ - examples/simple_middleware.rb
41
+ - examples/simple_middleware.rbs
38
42
  - lib/orthoses.rb
43
+ - lib/orthoses/attribute.rb
44
+ - lib/orthoses/avoid_recursive_ancestor_error.rb
39
45
  - lib/orthoses/builder.rb
40
46
  - lib/orthoses/call_tracer.rb
41
47
  - lib/orthoses/constant.rb
42
48
  - lib/orthoses/content.rb
43
49
  - lib/orthoses/content/duplication_checker.rb
50
+ - lib/orthoses/content/environment.rb
51
+ - lib/orthoses/content/header_builder.rb
44
52
  - lib/orthoses/create_file_by_name.rb
45
53
  - lib/orthoses/delegate_class.rb
46
54
  - lib/orthoses/filter.rb
@@ -48,15 +56,20 @@ files:
48
56
  - lib/orthoses/mixin.rb
49
57
  - lib/orthoses/object_space_all.rb
50
58
  - lib/orthoses/pp.rb
59
+ - lib/orthoses/rbs_prototype_rb.rb
51
60
  - lib/orthoses/store.rb
52
61
  - lib/orthoses/tap.rb
53
62
  - lib/orthoses/utils.rb
54
63
  - lib/orthoses/version.rb
55
64
  - lib/orthoses/walk.rb
65
+ - lib/orthoses/writer.rb
56
66
  - orthoses.gemspec
57
67
  - sig/orthoses.rbs
58
68
  - sig/orthoses/_call.rbs
59
69
  - sig/orthoses/_middle_ware.rbs
70
+ - sig/orthoses/attribute.rbs
71
+ - sig/orthoses/attribute/hook.rbs
72
+ - sig/orthoses/avoid_recursive_ancestor_error.rbs
60
73
  - sig/orthoses/builder.rbs
61
74
  - sig/orthoses/builder/call_logable.rbs
62
75
  - sig/orthoses/call_tracer.rbs
@@ -64,6 +77,8 @@ files:
64
77
  - sig/orthoses/constant.rbs
65
78
  - sig/orthoses/content.rbs
66
79
  - sig/orthoses/content/duplication_checker.rbs
80
+ - sig/orthoses/content/environment.rbs
81
+ - sig/orthoses/content/header_builder.rbs
67
82
  - sig/orthoses/create_file_by_name.rbs
68
83
  - sig/orthoses/delegate_class.rbs
69
84
  - sig/orthoses/filter.rbs
@@ -72,10 +87,12 @@ files:
72
87
  - sig/orthoses/name_space_error.rbs
73
88
  - sig/orthoses/object_space_all.rbs
74
89
  - sig/orthoses/pp.rbs
90
+ - sig/orthoses/rbs_prototype_rb.rbs
75
91
  - sig/orthoses/store.rbs
76
92
  - sig/orthoses/tap.rbs
77
93
  - sig/orthoses/utils.rbs
78
94
  - sig/orthoses/walk.rbs
95
+ - sig/orthoses/writer.rbs
79
96
  homepage: https://github.com/ksss/orthoses
80
97
  licenses:
81
98
  - MIT
@@ -97,7 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
97
114
  - !ruby/object:Gem::Version
98
115
  version: '0'
99
116
  requirements: []
100
- rubygems_version: 3.4.0.dev
117
+ rubygems_version: 3.3.7
101
118
  signing_key:
102
119
  specification_version: 4
103
120
  summary: Framework for Generate RBS