orthoses 0.1.0 → 0.4.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 64cbbb058a7d4dc7c5f6f0d8cc66a23a1b2026253ad20add3cc63777a1c42227
4
- data.tar.gz: 15742e8389d7fc4e129bca6ab48203f13dad5b2338eff73a2b4c530ba239d327
3
+ metadata.gz: 0e53d784825b1c759916988c4aaca8e6942fd89e0de4c73dff022f40ca265027
4
+ data.tar.gz: 7e6fdb9ac599274b713a9930d15bb8b81267c3afcc4a7ed3a6c747a13c711201
5
5
  SHA512:
6
- metadata.gz: 276874fcb60ce45b3b2ffe3388e963b596f65a466c4f36f5b3986b561f756f721d797e8217a27b6a292f988343fe8f4209886b876ba03e4512466b51903e4996
7
- data.tar.gz: 73b2a614b599980d20d2d0334d87f4f508b163beff9a766979d67f39f49213a634c9e907725efd1f7a51e1552b5db90e80f3d766bba024ff050d50c5d5522b5c
6
+ metadata.gz: 61b9855a1f2744de78e9993d4adb024133aa08eeefa4541f9371bbb9598c500b8e4af2618ff9904039bbb086a2fde61b714c6ae20bc466077b1b46601f9d6735
7
+ data.tar.gz: 6a2eaea1e8da4d1231dbcf4ebb4b4b92e228a03656a89385a439ff651b5dc204a9fb5071e8fb11a0fec35e95e85e6e1c332cc341ecb72302bd3d2623e3779585
data/Gemfile.lock ADDED
@@ -0,0 +1,61 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ orthoses (0.4.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
@@ -31,7 +31,7 @@ Orthoses::Builder.new do
31
31
  %r{app/models}.match?(path)
32
32
  }
33
33
  use YourCustom::Middleware
34
- use Orthoses::IncludeExtendPrepend
34
+ use Orthoses::Mixin
35
35
  use Orthoses::Constant
36
36
  use Orthoses::Walk,
37
37
  root: "Foo"
@@ -48,7 +48,7 @@ end.call
48
48
  Add constant signature to class/module.
49
49
  Signatures are predicted from constant values.
50
50
 
51
- ### Orthoses::IncludeExtendPrepend
51
+ ### Orthoses::Mixin
52
52
 
53
53
  Add module include/extend/prepend definition.
54
54
  It use `Module#{includeed,extended,prepended}` for capture.
@@ -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,48 @@
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::RBSPrototypeRB,
26
+ paths: Dir.glob('src/lib/minitest{.rb,/*.rb}'),
27
+ constant_filter: ->(_) { false },
28
+ mixin_filter: ->(_) { false }
29
+ run ->(){
30
+ require_relative 'src/lib/minitest'
31
+ require_relative 'src/lib/minitest/test'
32
+ require_relative 'src/lib/minitest/spec'
33
+ require_relative 'src/lib/minitest/parallel'
34
+ require_relative 'src/lib/minitest/mock'
35
+ require_relative 'src/lib/minitest/benchmark'
36
+
37
+ require_relative 'src/lib/minitest/pride_plugin'
38
+ }
39
+ end.call
40
+
41
+ sh "rbs -r mutex_m -I #{out} validate --silent"
42
+ out.join("manifest.yaml").write <<~YAML
43
+ dependencies:
44
+ - name: mutex_m
45
+ YAML
46
+ end
47
+
48
+ 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,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
@@ -5,7 +5,7 @@ module Orthoses
5
5
  # Builder.new do
6
6
  # use Orthoses::CreateFileByName
7
7
  # use Orthoses::Constant
8
- # use Orthoses::IncludeExtendPrepend
8
+ # use Orthoses::Mixin
9
9
  # use Orthoses::Walk,
10
10
  # root: "Foo"
11
11
  # run ->() { require 'foo' }
@@ -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
@@ -0,0 +1,60 @@
1
+ module Orthoses
2
+ class Content
3
+ # Check and drop duplication method, const etc...
4
+ class DuplicationChecker
5
+ def initialize(decl)
6
+ @decl = decl
7
+ end
8
+
9
+ def update_decl
10
+ uniq_map = {}
11
+ @decl.members.reverse_each do |member|
12
+ key = member_key(member)
13
+ if uniq_map.key?(key)
14
+ Orthoses.logger.warn("#{@decl.name}::#{member_to_s(member)} was droped since duplication")
15
+ else
16
+ uniq_map[key] = member
17
+ end
18
+ end
19
+ drop_known_method_definition(uniq_map)
20
+ @decl.members.replace(uniq_map.values.reverse)
21
+ end
22
+
23
+ private
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.each do |member|
30
+ case member
31
+ when RBS::AST::Members::MethodDefinition, RBS::AST::Members::Alias
32
+ uniq_map.delete(member_key(member))
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ def member_to_s(member)
40
+ out = StringIO.new
41
+ RBS::Writer.new(out: out).write_member(member)
42
+ out.string.chomp
43
+ end
44
+
45
+ def member_key(member)
46
+ case member
47
+ when RBS::AST::Members::MethodDefinition
48
+ # member.types.hash is different
49
+ [member.class, member.name, member.kind]
50
+ when RBS::AST::Members::LocationOnly
51
+ [member.class]
52
+ when RBS::AST::Members::Alias
53
+ [RBS::AST::Members::MethodDefinition, member.new_name, member.kind]
54
+ else
55
+ [member.class, member.name]
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,72 @@
1
+ module Orthoses
2
+ class Content
3
+ class Environment
4
+ def initialize(constant_filter: nil, mixin_filter: nil)
5
+ @load_env = RBS::Environment.new
6
+ @known_env = Utils.rbs_environment(collection: true)
7
+ @constant_filter = constant_filter
8
+ @mixin_filter = mixin_filter
9
+ end
10
+
11
+ def <<(decl)
12
+ if known_class_entry = @known_env.class_decls[decl.name.absolute!]
13
+ decl.type_params.replace(known_class_entry.primary.decl.type_params)
14
+ end
15
+ @load_env << decl
16
+ rescue RBS::DuplicatedDeclarationError => err
17
+ Orthoses.logger.warn(err.inspect)
18
+ end
19
+
20
+ def write_to(store:)
21
+ each do |add_content|
22
+ content = store[add_content.name]
23
+ content.header ||= add_content.header
24
+ content.concat(add_content.body)
25
+ end
26
+ end
27
+
28
+ def each
29
+ header_builder = HeaderBuilder.new(env: @load_env)
30
+
31
+ @load_env.class_decls.each do |type_name, m_entry|
32
+ name = type_name.relative!.to_s
33
+ content = Content.new(name: name)
34
+ content.header = header_builder.build(entry: m_entry, name_hint: name)
35
+ decls_to_lines(m_entry.decls.map(&:decl)).each do |line|
36
+ content << line
37
+ end
38
+ yield content
39
+ end
40
+
41
+ @load_env.interface_decls.each do |type_name, s_entry|
42
+ name = type_name.relative!.to_s
43
+ content = Content.new(name: name)
44
+ content.header = header_builder.build(entry: s_entry)
45
+ decls_to_lines([s_entry.decl]).each do |line|
46
+ content << line
47
+ end
48
+ yield content
49
+ end
50
+ end
51
+
52
+ def decls_to_lines(decls)
53
+ out = StringIO.new
54
+ writer = RBS::Writer.new(out: out)
55
+ decls.each do |decl|
56
+ next unless decl.respond_to?(:members)
57
+ decl.members.each do |member|
58
+ next if member.respond_to?(:members)
59
+ case member
60
+ when RBS::AST::Declarations::Constant
61
+ next unless @constant_filter.nil? || @constant_filter.call(member)
62
+ when RBS::AST::Members::Mixin
63
+ next unless @mixin_filter.nil? || @mixin_filter.call(member)
64
+ end
65
+ writer.write_member(member)
66
+ end
67
+ end
68
+ out.string.each_line(chomp: true).to_a
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,93 @@
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
+
52
+ super_class_name = @resolver.resolve(primary.decl.super_class.name, context: context) || primary.decl.super_class.name
53
+ if primary.decl.super_class.args.empty?
54
+ if super_class_entry = @env.class_decls[super_class_name.absolute!]
55
+ super_primary = super_class_entry.primary
56
+ " < #{name_and_args(super_class_name, super_primary.decl.type_params.map { :untyped })}"
57
+ else
58
+ " < #{name_and_args(super_class_name, [])}"
59
+ end
60
+ else
61
+ " < #{name_and_args(super_class_name, primary.decl.super_class.args)}"
62
+ end
63
+ end
64
+
65
+ def build_interface(entry:, name_hint: nil)
66
+ full_name = name_hint || entry.decl.name.relative!
67
+ "interface #{name_and_params(full_name, entry.decl.type_params)}"
68
+ end
69
+
70
+ def name_and_params(name, params)
71
+ if params.empty?
72
+ "#{name}"
73
+ else
74
+ ps = params.each.map do |param|
75
+ param.to_s
76
+ end
77
+
78
+ "#{name}[#{ps.join(", ")}]"
79
+ end
80
+ end
81
+
82
+ def name_and_args(name, args)
83
+ if name && args
84
+ if args.empty?
85
+ "#{name}"
86
+ else
87
+ "#{name}[#{args.join(", ")}]"
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -1,5 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'orthoses/content/duplication_checker'
4
+ require 'orthoses/content/environment'
5
+ require 'orthoses/content/header_builder'
6
+
3
7
  module Orthoses
4
8
  # Common interface for output.
5
9
  # Orthoses::Content expect to use result of middleware.
@@ -17,31 +21,79 @@ module Orthoses
17
21
  attr_accessor :header
18
22
 
19
23
  def initialize(name:)
24
+ Orthoses.logger.debug("Create Orthoses::Content for #{name}")
20
25
  @name = name
21
26
  @body = []
22
27
  @header = nil
23
28
  end
24
29
 
25
30
  def <<(line)
26
- Orthoses.logger.debug("[#{name}] << #{line} on #{__FILE__}:#{__LINE__}")
27
31
  @body << line
28
32
  end
29
33
 
30
34
  def concat(other)
31
- Orthoses.logger.debug("[#{name}] concat #{other} on #{__FILE__}:#{__LINE__}")
32
35
  @body.concat(other)
33
36
  end
34
37
 
35
38
  def to_rbs
36
- if @header.nil?
37
- auto_header
38
- end
39
- 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
40
46
  end
41
47
 
42
48
  private
43
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
+
44
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
+
45
97
  val = Object.const_get(name)
46
98
 
47
99
  case val
@@ -85,29 +137,5 @@ module Orthoses
85
137
  end
86
138
  end
87
139
  end
88
-
89
- def body_uniq(rbs)
90
- buffer = RBS::Buffer.new(
91
- name: "orthoses/content.rb",
92
- content: rbs
93
- )
94
- out = StringIO.new
95
- writer = RBS::Writer.new(out: out)
96
- decls = RBS::Parser.parse_signature(buffer).map do |parsed_decl|
97
- before_members = parsed_decl.members.dup
98
- parsed_decl.members.uniq! { |m| [m.class, m.respond_to?(:name) ? m.name : nil] }
99
- (before_members - parsed_decl.members).each do |droped_member|
100
- Orthoses.logger.warn("#{parsed_decl.name}::#{droped_member.name.to_s}: #{droped_member.to_s} was droped since duplication")
101
- end
102
- parsed_decl
103
- end
104
- writer.write(decls)
105
- out.string
106
- rescue RBS::ParsingError
107
- puts "```rbs"
108
- puts rbs
109
- puts "```"
110
- raise
111
- end
112
140
  end
113
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,17 +29,22 @@ 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
- store[subclass_name].header = "class #{subclass_name} < #{delegate_to_class_name}"
32
+
33
+ header = "class #{subclass_name} < ::#{delegate_to_class_name}#{temporary_type_params(delegate_to_class_name)}"
34
+ store[subclass_name].header = header
33
35
  end
34
36
  end
35
37
  store
36
38
  end
37
39
 
38
- def from_DelegateClass?(klass)
39
- klass.name.nil? &&
40
- klass.superclass == Delegator &&
41
- klass.instance_methods.include?(:__setobj__) &&
42
- klass.instance_method(:__setobj__).source_location.first.end_with?("delegate.rb")
40
+ def temporary_type_params(name)
41
+ Utils.known_type_params(name)&.then do |params|
42
+ if params.empty?
43
+ nil
44
+ else
45
+ "[#{params.map { :untyped }.join(', ')}]"
46
+ end
47
+ end
43
48
  end
44
49
  end
45
50
  end
@@ -11,79 +11,16 @@ module Orthoses
11
11
 
12
12
  def call
13
13
  @loader.call.tap do |store|
14
- tmp_env = RBS::Environment.new
15
-
14
+ env = Content::Environment.new
16
15
  @paths.each do |path|
17
16
  Orthoses.logger.debug("Load #{path}")
18
17
  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)
18
+ RBS::Parser.parse_signature(buffer).each do |decl|
19
+ env << decl
83
20
  end
84
21
  end
22
+ env.write_to(store: store)
85
23
  end
86
- out.string.each_line(chomp: true).to_a
87
24
  end
88
25
  end
89
26
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Orthoses
4
- class IncludeExtendPrepend
4
+ class Mixin
5
5
  def initialize(loader, if: nil)
6
6
  @loader = loader
7
7
  @if = binding.local_variable_get(:if)
@@ -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,35 @@
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)
7
+ @loader = loader
8
+ @paths = paths
9
+ @constant_filter = constant_filter
10
+ @mixin_filter = mixin_filter
11
+ end
12
+
13
+ def call
14
+ @loader.call.tap do |store|
15
+ parser = RBS::Prototype::RB.new
16
+ @paths.each do |path|
17
+ begin
18
+ Orthoses.logger.debug("parse #{path} by RBS::Prototype::RB")
19
+ parser.parse File.read(path.to_s)
20
+ rescue => err
21
+ Orthoses.logger.error("Parse error #{err.inspect} by RBS::Prototype::RB #{path}")
22
+ end
23
+ end
24
+ env = Orthoses::Content::Environment.new(
25
+ constant_filter: @constant_filter,
26
+ mixin_filter: @mixin_filter,
27
+ )
28
+ parser.decls.each do |decl|
29
+ env << decl
30
+ end
31
+ env.write_to(store: store)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -63,11 +63,11 @@ 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
 
@@ -117,10 +117,13 @@ module Orthoses
117
117
  "{ #{object.map { |k, v| "#{k}: #{object_to_rbs(v, strict: strict)}" }.join(', ')} }"
118
118
  else
119
119
  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
120
+ values = object.values.map { |v| object_to_rbs(v, strict: strict) }.uniq
121
121
  "Hash[#{keys.join(' | ')}, #{values.join(' | ')}]"
122
122
  end
123
123
  end
124
+ when ARGF
125
+ # see also https://github.com/ruby/rbs/pull/975
126
+ 'untyped'
124
127
  else
125
128
  Utils.module_name(object.class) || 'untyped'
126
129
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Orthoses
4
- VERSION = "0.1.0"
4
+ VERSION = "0.4.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,7 @@
3
3
  require 'rbs'
4
4
  require 'pathname'
5
5
 
6
+ require_relative 'orthoses/avoid_recursive_ancestor_error'
6
7
  require_relative 'orthoses/builder'
7
8
  require_relative 'orthoses/call_tracer'
8
9
  require_relative 'orthoses/constant'
@@ -10,15 +11,17 @@ require_relative 'orthoses/content'
10
11
  require_relative 'orthoses/create_file_by_name'
11
12
  require_relative 'orthoses/delegate_class'
12
13
  require_relative 'orthoses/filter'
13
- require_relative 'orthoses/include_extend_prepend'
14
+ require_relative 'orthoses/mixin'
14
15
  require_relative 'orthoses/load_rbs'
15
16
  require_relative 'orthoses/object_space_all'
16
17
  require_relative 'orthoses/pp'
18
+ require_relative 'orthoses/rbs_prototype_rb'
17
19
  require_relative 'orthoses/store'
18
20
  require_relative 'orthoses/tap'
19
21
  require_relative 'orthoses/utils'
20
22
  require_relative 'orthoses/version'
21
23
  require_relative 'orthoses/walk'
24
+ require_relative 'orthoses/writer'
22
25
 
23
26
  module Orthoses
24
27
  class ConstLoadError < StandardError
@@ -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
@@ -0,0 +1,4 @@
1
+ # THIS IS GENERATED CODE from `$ rake generate_self_sig`
2
+
3
+ class Orthoses::Content::DuplicationChecker
4
+ end
@@ -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
@@ -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::IncludeExtendPrepend
3
+ class Orthoses::Mixin
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
@@ -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
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.1.0
4
+ version: 0.4.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-08 00:00:00.000000000 Z
11
+ date: 2022-05-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rbs
@@ -33,47 +33,62 @@ 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/avoid_recursive_ancestor_error.rb
39
44
  - lib/orthoses/builder.rb
40
45
  - lib/orthoses/call_tracer.rb
41
46
  - lib/orthoses/constant.rb
42
47
  - lib/orthoses/content.rb
48
+ - lib/orthoses/content/duplication_checker.rb
49
+ - lib/orthoses/content/environment.rb
50
+ - lib/orthoses/content/header_builder.rb
43
51
  - lib/orthoses/create_file_by_name.rb
44
52
  - lib/orthoses/delegate_class.rb
45
53
  - lib/orthoses/filter.rb
46
- - lib/orthoses/include_extend_prepend.rb
47
54
  - lib/orthoses/load_rbs.rb
55
+ - lib/orthoses/mixin.rb
48
56
  - lib/orthoses/object_space_all.rb
49
57
  - lib/orthoses/pp.rb
58
+ - lib/orthoses/rbs_prototype_rb.rb
50
59
  - lib/orthoses/store.rb
51
60
  - lib/orthoses/tap.rb
52
61
  - lib/orthoses/utils.rb
53
62
  - lib/orthoses/version.rb
54
63
  - lib/orthoses/walk.rb
64
+ - lib/orthoses/writer.rb
55
65
  - orthoses.gemspec
56
66
  - sig/orthoses.rbs
57
67
  - sig/orthoses/_call.rbs
58
68
  - sig/orthoses/_middle_ware.rbs
69
+ - sig/orthoses/avoid_recursive_ancestor_error.rbs
59
70
  - sig/orthoses/builder.rbs
60
71
  - sig/orthoses/builder/call_logable.rbs
61
72
  - sig/orthoses/call_tracer.rbs
62
73
  - sig/orthoses/const_load_error.rbs
63
74
  - sig/orthoses/constant.rbs
64
75
  - sig/orthoses/content.rbs
76
+ - sig/orthoses/content/duplication_checker.rbs
77
+ - sig/orthoses/content/environment.rbs
65
78
  - sig/orthoses/create_file_by_name.rbs
66
79
  - sig/orthoses/delegate_class.rbs
67
80
  - sig/orthoses/filter.rbs
68
- - sig/orthoses/include_extend_prepend.rbs
69
81
  - sig/orthoses/load_rbs.rbs
82
+ - sig/orthoses/mixin.rbs
70
83
  - sig/orthoses/name_space_error.rbs
71
84
  - sig/orthoses/object_space_all.rbs
72
85
  - sig/orthoses/pp.rbs
86
+ - sig/orthoses/rbs_prototype_rb.rbs
73
87
  - sig/orthoses/store.rbs
74
88
  - sig/orthoses/tap.rbs
75
89
  - sig/orthoses/utils.rbs
76
90
  - sig/orthoses/walk.rbs
91
+ - sig/orthoses/writer.rbs
77
92
  homepage: https://github.com/ksss/orthoses
78
93
  licenses:
79
94
  - MIT
@@ -95,7 +110,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
95
110
  - !ruby/object:Gem::Version
96
111
  version: '0'
97
112
  requirements: []
98
- rubygems_version: 3.4.0.dev
113
+ rubygems_version: 3.3.7
99
114
  signing_key:
100
115
  specification_version: 4
101
116
  summary: Framework for Generate RBS