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 +4 -4
- data/Gemfile.lock +61 -0
- data/README.md +18 -2
- data/examples/minitest/Rakefile +48 -0
- data/examples/simple_middleware.rb +11 -0
- data/examples/simple_middleware.rbs +7 -0
- data/lib/orthoses/avoid_recursive_ancestor_error.rb +22 -0
- data/lib/orthoses/builder.rb +1 -1
- data/lib/orthoses/call_tracer.rb +3 -2
- data/lib/orthoses/content/duplication_checker.rb +60 -0
- data/lib/orthoses/content/environment.rb +72 -0
- data/lib/orthoses/content/header_builder.rb +93 -0
- data/lib/orthoses/content.rb +58 -30
- data/lib/orthoses/create_file_by_name.rb +7 -1
- data/lib/orthoses/delegate_class.rb +11 -6
- data/lib/orthoses/load_rbs.rb +4 -67
- data/lib/orthoses/{include_extend_prepend.rb → mixin.rb} +2 -10
- data/lib/orthoses/rbs_prototype_rb.rb +35 -0
- data/lib/orthoses/utils.rb +6 -3
- data/lib/orthoses/version.rb +1 -1
- data/lib/orthoses/writer.rb +16 -0
- data/lib/orthoses.rb +4 -1
- data/sig/orthoses/avoid_recursive_ancestor_error.rbs +7 -0
- data/sig/orthoses/call_tracer.rbs +1 -0
- data/sig/orthoses/content/duplication_checker.rbs +4 -0
- data/sig/orthoses/content/environment.rbs +13 -0
- data/sig/orthoses/content.rbs +3 -0
- data/sig/orthoses/delegate_class.rbs +3 -0
- data/sig/orthoses/load_rbs.rbs +4 -0
- data/sig/orthoses/{include_extend_prepend.rbs → mixin.rbs} +1 -1
- data/sig/orthoses/object_space_all.rbs +3 -0
- data/sig/orthoses/rbs_prototype_rb.rbs +10 -0
- data/sig/orthoses/tap.rbs +3 -0
- data/sig/orthoses/writer.rbs +7 -0
- metadata +20 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0e53d784825b1c759916988c4aaca8e6942fd89e0de4c73dff022f40ca265027
|
4
|
+
data.tar.gz: 7e6fdb9ac599274b713a9930d15bb8b81267c3afcc4a7ed3a6c747a13c711201
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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::
|
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::
|
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,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
|
data/lib/orthoses/builder.rb
CHANGED
data/lib/orthoses/call_tracer.rb
CHANGED
@@ -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
|
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
|
data/lib/orthoses/content.rb
CHANGED
@@ -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
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
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
|
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
|
-
|
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
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
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
|
data/lib/orthoses/load_rbs.rb
CHANGED
@@ -11,79 +11,16 @@ module Orthoses
|
|
11
11
|
|
12
12
|
def call
|
13
13
|
@loader.call.tap do |store|
|
14
|
-
|
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
|
-
|
20
|
-
|
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
|
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
|
-
|
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
|
data/lib/orthoses/utils.rb
CHANGED
@@ -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 { |
|
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
|
data/lib/orthoses/version.rb
CHANGED
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/
|
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,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
|
data/sig/orthoses/content.rbs
CHANGED
data/sig/orthoses/load_rbs.rbs
CHANGED
@@ -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
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.
|
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-
|
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.
|
113
|
+
rubygems_version: 3.3.7
|
99
114
|
signing_key:
|
100
115
|
specification_version: 4
|
101
116
|
summary: Framework for Generate RBS
|