steep 0.11.1 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +27 -0
- data/.gitmodules +3 -0
- data/CHANGELOG.md +5 -0
- data/README.md +48 -90
- data/Rakefile +10 -6
- data/Steepfile +1 -0
- data/bin/setup +1 -0
- data/bin/smoke_runner.rb +9 -14
- data/exe/rbs +3 -0
- data/exe/ruby-signature +3 -0
- data/exe/steep +1 -0
- data/lib/steep.rb +32 -26
- data/lib/steep/annotation_parser.rb +167 -0
- data/lib/steep/ast/annotation/collection.rb +7 -7
- data/lib/steep/ast/types.rb +60 -0
- data/lib/steep/ast/types/any.rb +1 -1
- data/lib/steep/ast/types/factory.rb +535 -0
- data/lib/steep/ast/types/name.rb +3 -3
- data/lib/steep/ast/types/var.rb +1 -1
- data/lib/steep/cli.rb +56 -240
- data/lib/steep/drivers/annotations.rb +36 -19
- data/lib/steep/drivers/check.rb +55 -91
- data/lib/steep/drivers/init.rb +54 -0
- data/lib/steep/drivers/langserver.rb +241 -150
- data/lib/steep/drivers/print_project.rb +56 -0
- data/lib/steep/drivers/signature_error_printer.rb +25 -0
- data/lib/steep/drivers/trace_printer.rb +25 -0
- data/lib/steep/drivers/utils/driver_helper.rb +26 -0
- data/lib/steep/drivers/validate.rb +18 -38
- data/lib/steep/drivers/vendor.rb +46 -0
- data/lib/steep/drivers/watch.rb +78 -140
- data/lib/steep/errors.rb +22 -13
- data/lib/steep/interface/interface.rb +91 -0
- data/lib/steep/interface/method.rb +0 -4
- data/lib/steep/interface/method_type.rb +362 -2
- data/lib/steep/interface/substitution.rb +22 -0
- data/lib/steep/project.rb +25 -233
- data/lib/steep/project/dsl.rb +132 -0
- data/lib/steep/project/file.rb +93 -76
- data/lib/steep/project/file_loader.rb +63 -0
- data/lib/steep/project/options.rb +7 -0
- data/lib/steep/project/target.rb +190 -0
- data/lib/steep/signature/errors.rb +25 -77
- data/lib/steep/signature/validator.rb +122 -0
- data/lib/steep/source.rb +12 -7
- data/lib/steep/subtyping/check.rb +357 -633
- data/lib/steep/subtyping/constraints.rb +2 -2
- data/lib/steep/subtyping/trace.rb +23 -0
- data/lib/steep/type_construction.rb +509 -455
- data/lib/steep/type_inference/constant_env.rb +16 -24
- data/lib/steep/type_inference/type_env.rb +26 -18
- data/lib/steep/version.rb +1 -1
- data/sample/Steepfile +6 -0
- data/sample/lib/conference.rb +12 -0
- data/sample/sig/conference.rbs +6 -0
- data/smoke/alias/Steepfile +4 -0
- data/smoke/alias/a.rb +2 -2
- data/smoke/alias/{a.rbi → a.rbs} +1 -1
- data/smoke/and/Steepfile +4 -0
- data/smoke/array/Steepfile +4 -0
- data/smoke/array/a.rb +2 -2
- data/smoke/array/b.rb +4 -4
- data/smoke/array/c.rb +2 -2
- data/smoke/block/Steepfile +5 -0
- data/smoke/block/{a.rbi → a.rbs} +1 -1
- data/smoke/block/{c.rbi → c.rbs} +0 -0
- data/smoke/block/d.rb +6 -6
- data/smoke/case/Steepfile +4 -0
- data/smoke/case/a.rb +4 -3
- data/smoke/class/Steepfile +4 -0
- data/smoke/class/a.rb +1 -4
- data/smoke/class/a.rbs +24 -0
- data/smoke/class/h.rb +6 -2
- data/smoke/class/{h.rbi → h.rbs} +1 -2
- data/smoke/class/i.rb +1 -2
- data/smoke/class/i.rbs +9 -0
- data/smoke/const/Steepfile +4 -0
- data/smoke/dstr/Steepfile +4 -0
- data/smoke/ensure/Steepfile +4 -0
- data/smoke/ensure/a.rb +1 -1
- data/smoke/enumerator/Steepfile +4 -0
- data/smoke/enumerator/a.rb +7 -7
- data/smoke/enumerator/b.rb +6 -6
- data/smoke/extension/Steepfile +4 -0
- data/smoke/extension/{a.rbi → a.rbs} +2 -2
- data/smoke/extension/{e.rbi → e.rbs} +2 -2
- data/smoke/hash/Steepfile +4 -0
- data/smoke/hash/{a.rbi → a.rbs} +0 -0
- data/smoke/hash/b.rb +2 -2
- data/smoke/hash/c.rb +1 -1
- data/smoke/hash/e.rbs +3 -0
- data/smoke/hash/f.rb +1 -1
- data/smoke/hello/Steepfile +4 -0
- data/smoke/hello/hello.rbs +7 -0
- data/smoke/if/Steepfile +4 -0
- data/smoke/implements/Steepfile +4 -0
- data/smoke/implements/a.rbs +6 -0
- data/smoke/initialize/Steepfile +4 -0
- data/smoke/initialize/a.rbs +3 -0
- data/smoke/integer/Steepfile +4 -0
- data/smoke/integer/a.rb +5 -3
- data/smoke/interface/Steepfile +4 -0
- data/smoke/interface/{a.rbi → a.rbs} +0 -0
- data/smoke/kwbegin/Steepfile +4 -0
- data/smoke/lambda/Steepfile +4 -0
- data/smoke/lambda/a.rb +9 -2
- data/smoke/literal/Steepfile +4 -0
- data/smoke/literal/{literal_methods.rbi → literal_methods.rbs} +0 -0
- data/smoke/map/Steepfile +4 -0
- data/smoke/map/a.rb +1 -1
- data/smoke/method/Steepfile +4 -0
- data/smoke/method/{a.rbi → a.rbs} +0 -0
- data/smoke/method/b.rb +1 -4
- data/smoke/method/d.rb +1 -0
- data/smoke/method/d.rbs +3 -0
- data/smoke/module/Steepfile +4 -0
- data/smoke/module/a.rb +1 -1
- data/smoke/module/a.rbs +16 -0
- data/smoke/module/c.rb +1 -1
- data/smoke/regexp/Steepfile +4 -0
- data/smoke/regexp/a.rb +2 -2
- data/smoke/regexp/b.rb +16 -16
- data/smoke/regression/Steepfile +5 -0
- data/smoke/regression/array.rb +2 -2
- data/smoke/regression/hash.rb +2 -2
- data/smoke/regression/poly_new.rb +2 -0
- data/smoke/regression/poly_new.rbs +4 -0
- data/smoke/regression/set_divide.rb +2 -2
- data/smoke/rescue/Steepfile +4 -0
- data/smoke/rescue/a.rb +1 -1
- data/smoke/self/Steepfile +4 -0
- data/smoke/self/a.rbs +4 -0
- data/smoke/skip/Steepfile +4 -0
- data/smoke/stdout/Steepfile +4 -0
- data/smoke/stdout/{a.rbi → a.rbs} +1 -1
- data/smoke/super/Steepfile +4 -0
- data/smoke/super/a.rbs +10 -0
- data/smoke/type_case/Steepfile +4 -0
- data/smoke/type_case/a.rb +1 -1
- data/smoke/yield/Steepfile +4 -0
- data/smoke/yield/a.rb +2 -2
- data/steep.gemspec +14 -7
- data/vendor/ruby-signature/.github/workflows/ruby.yml +27 -0
- data/vendor/ruby-signature/.gitignore +12 -0
- data/vendor/ruby-signature/.rubocop.yml +15 -0
- data/vendor/ruby-signature/BSDL +22 -0
- data/vendor/ruby-signature/COPYING +56 -0
- data/vendor/ruby-signature/Gemfile +6 -0
- data/vendor/ruby-signature/README.md +93 -0
- data/vendor/ruby-signature/Rakefile +66 -0
- data/vendor/ruby-signature/bin/annotate-with-rdoc +156 -0
- data/vendor/ruby-signature/bin/console +14 -0
- data/vendor/ruby-signature/bin/query-rdoc +103 -0
- data/vendor/ruby-signature/bin/setup +10 -0
- data/vendor/ruby-signature/bin/sort +88 -0
- data/vendor/ruby-signature/bin/test_runner.rb +17 -0
- data/vendor/ruby-signature/docs/CONTRIBUTING.md +97 -0
- data/vendor/ruby-signature/docs/sigs.md +148 -0
- data/vendor/ruby-signature/docs/stdlib.md +152 -0
- data/vendor/ruby-signature/docs/syntax.md +528 -0
- data/vendor/ruby-signature/exe/rbs +3 -0
- data/vendor/ruby-signature/exe/ruby-signature +7 -0
- data/vendor/ruby-signature/lib/ruby/signature.rb +64 -0
- data/vendor/ruby-signature/lib/ruby/signature/ast/annotation.rb +29 -0
- data/vendor/ruby-signature/lib/ruby/signature/ast/comment.rb +29 -0
- data/vendor/ruby-signature/lib/ruby/signature/ast/declarations.rb +391 -0
- data/vendor/ruby-signature/lib/ruby/signature/ast/members.rb +364 -0
- data/vendor/ruby-signature/lib/ruby/signature/buffer.rb +52 -0
- data/vendor/ruby-signature/lib/ruby/signature/builtin_names.rb +54 -0
- data/vendor/ruby-signature/lib/ruby/signature/cli.rb +534 -0
- data/vendor/ruby-signature/lib/ruby/signature/constant.rb +28 -0
- data/vendor/ruby-signature/lib/ruby/signature/constant_table.rb +152 -0
- data/vendor/ruby-signature/lib/ruby/signature/definition.rb +172 -0
- data/vendor/ruby-signature/lib/ruby/signature/definition_builder.rb +921 -0
- data/vendor/ruby-signature/lib/ruby/signature/environment.rb +283 -0
- data/vendor/ruby-signature/lib/ruby/signature/environment_loader.rb +138 -0
- data/vendor/ruby-signature/lib/ruby/signature/environment_walker.rb +126 -0
- data/vendor/ruby-signature/lib/ruby/signature/errors.rb +189 -0
- data/vendor/ruby-signature/lib/ruby/signature/location.rb +104 -0
- data/vendor/ruby-signature/lib/ruby/signature/method_type.rb +125 -0
- data/vendor/ruby-signature/lib/ruby/signature/namespace.rb +93 -0
- data/vendor/ruby-signature/lib/ruby/signature/parser.y +1343 -0
- data/vendor/ruby-signature/lib/ruby/signature/prototype/rb.rb +441 -0
- data/vendor/ruby-signature/lib/ruby/signature/prototype/rbi.rb +579 -0
- data/vendor/ruby-signature/lib/ruby/signature/prototype/runtime.rb +383 -0
- data/vendor/ruby-signature/lib/ruby/signature/substitution.rb +48 -0
- data/vendor/ruby-signature/lib/ruby/signature/test.rb +28 -0
- data/vendor/ruby-signature/lib/ruby/signature/test/errors.rb +63 -0
- data/vendor/ruby-signature/lib/ruby/signature/test/hook.rb +290 -0
- data/vendor/ruby-signature/lib/ruby/signature/test/setup.rb +58 -0
- data/vendor/ruby-signature/lib/ruby/signature/test/spy.rb +324 -0
- data/vendor/ruby-signature/lib/ruby/signature/test/test_helper.rb +185 -0
- data/vendor/ruby-signature/lib/ruby/signature/test/type_check.rb +256 -0
- data/vendor/ruby-signature/lib/ruby/signature/type_name.rb +72 -0
- data/vendor/ruby-signature/lib/ruby/signature/types.rb +932 -0
- data/vendor/ruby-signature/lib/ruby/signature/variance_calculator.rb +140 -0
- data/vendor/ruby-signature/lib/ruby/signature/vendorer.rb +49 -0
- data/vendor/ruby-signature/lib/ruby/signature/version.rb +5 -0
- data/vendor/ruby-signature/lib/ruby/signature/writer.rb +271 -0
- data/vendor/ruby-signature/ruby-signature.gemspec +45 -0
- data/vendor/ruby-signature/stdlib/abbrev/abbrev.rbs +3 -0
- data/vendor/ruby-signature/stdlib/base64/base64.rbs +15 -0
- data/vendor/ruby-signature/stdlib/builtin/array.rbs +1997 -0
- data/vendor/ruby-signature/stdlib/builtin/basic_object.rbs +280 -0
- data/vendor/ruby-signature/stdlib/builtin/binding.rbs +177 -0
- data/vendor/ruby-signature/stdlib/builtin/builtin.rbs +35 -0
- data/vendor/ruby-signature/stdlib/builtin/class.rbs +145 -0
- data/vendor/ruby-signature/stdlib/builtin/comparable.rbs +116 -0
- data/vendor/ruby-signature/stdlib/builtin/complex.rbs +400 -0
- data/vendor/ruby-signature/stdlib/builtin/constants.rbs +37 -0
- data/vendor/ruby-signature/stdlib/builtin/data.rbs +5 -0
- data/vendor/ruby-signature/stdlib/builtin/deprecated.rbs +2 -0
- data/vendor/ruby-signature/stdlib/builtin/dir.rbs +419 -0
- data/vendor/ruby-signature/stdlib/builtin/encoding.rbs +606 -0
- data/vendor/ruby-signature/stdlib/builtin/enumerable.rbs +404 -0
- data/vendor/ruby-signature/stdlib/builtin/enumerator.rbs +260 -0
- data/vendor/ruby-signature/stdlib/builtin/errno.rbs +781 -0
- data/vendor/ruby-signature/stdlib/builtin/errors.rbs +582 -0
- data/vendor/ruby-signature/stdlib/builtin/exception.rbs +193 -0
- data/vendor/ruby-signature/stdlib/builtin/false_class.rbs +40 -0
- data/vendor/ruby-signature/stdlib/builtin/fiber.rbs +68 -0
- data/vendor/ruby-signature/stdlib/builtin/fiber_error.rbs +12 -0
- data/vendor/ruby-signature/stdlib/builtin/file.rbs +476 -0
- data/vendor/ruby-signature/stdlib/builtin/file_test.rbs +59 -0
- data/vendor/ruby-signature/stdlib/builtin/float.rbs +696 -0
- data/vendor/ruby-signature/stdlib/builtin/gc.rbs +121 -0
- data/vendor/ruby-signature/stdlib/builtin/hash.rbs +1029 -0
- data/vendor/ruby-signature/stdlib/builtin/integer.rbs +710 -0
- data/vendor/ruby-signature/stdlib/builtin/io.rbs +683 -0
- data/vendor/ruby-signature/stdlib/builtin/kernel.rbs +574 -0
- data/vendor/ruby-signature/stdlib/builtin/marshal.rbs +135 -0
- data/vendor/ruby-signature/stdlib/builtin/match_data.rbs +141 -0
- data/vendor/ruby-signature/stdlib/builtin/math.rbs +66 -0
- data/vendor/ruby-signature/stdlib/builtin/method.rbs +182 -0
- data/vendor/ruby-signature/stdlib/builtin/module.rbs +248 -0
- data/vendor/ruby-signature/stdlib/builtin/nil_class.rbs +82 -0
- data/vendor/ruby-signature/stdlib/builtin/numeric.rbs +409 -0
- data/vendor/ruby-signature/stdlib/builtin/object.rbs +824 -0
- data/vendor/ruby-signature/stdlib/builtin/proc.rbs +426 -0
- data/vendor/ruby-signature/stdlib/builtin/process.rbs +354 -0
- data/vendor/ruby-signature/stdlib/builtin/random.rbs +93 -0
- data/vendor/ruby-signature/stdlib/builtin/range.rbs +226 -0
- data/vendor/ruby-signature/stdlib/builtin/rational.rbs +424 -0
- data/vendor/ruby-signature/stdlib/builtin/rb_config.rbs +10 -0
- data/vendor/ruby-signature/stdlib/builtin/regexp.rbs +131 -0
- data/vendor/ruby-signature/stdlib/builtin/ruby_vm.rbs +14 -0
- data/vendor/ruby-signature/stdlib/builtin/signal.rbs +55 -0
- data/vendor/ruby-signature/stdlib/builtin/string.rbs +770 -0
- data/vendor/ruby-signature/stdlib/builtin/string_io.rbs +13 -0
- data/vendor/ruby-signature/stdlib/builtin/struct.rbs +40 -0
- data/vendor/ruby-signature/stdlib/builtin/symbol.rbs +230 -0
- data/vendor/ruby-signature/stdlib/builtin/thread.rbs +1112 -0
- data/vendor/ruby-signature/stdlib/builtin/thread_group.rbs +23 -0
- data/vendor/ruby-signature/stdlib/builtin/time.rbs +739 -0
- data/vendor/ruby-signature/stdlib/builtin/trace_point.rbs +91 -0
- data/vendor/ruby-signature/stdlib/builtin/true_class.rbs +46 -0
- data/vendor/ruby-signature/stdlib/builtin/unbound_method.rbs +159 -0
- data/vendor/ruby-signature/stdlib/builtin/warning.rbs +17 -0
- data/vendor/ruby-signature/stdlib/erb/erb.rbs +18 -0
- data/vendor/ruby-signature/stdlib/find/find.rbs +44 -0
- data/vendor/ruby-signature/stdlib/pathname/pathname.rbs +21 -0
- data/vendor/ruby-signature/stdlib/prime/integer-extension.rbs +23 -0
- data/vendor/ruby-signature/stdlib/prime/prime.rbs +188 -0
- data/vendor/ruby-signature/stdlib/securerandom/securerandom.rbs +9 -0
- data/vendor/ruby-signature/stdlib/set/set.rbs +77 -0
- data/vendor/ruby-signature/stdlib/tmpdir/tmpdir.rbs +53 -0
- metadata +244 -54
- data/.travis.yml +0 -7
- data/lib/steep/ast/signature/alias.rb +0 -19
- data/lib/steep/ast/signature/class.rb +0 -33
- data/lib/steep/ast/signature/const.rb +0 -17
- data/lib/steep/ast/signature/env.rb +0 -138
- data/lib/steep/ast/signature/extension.rb +0 -21
- data/lib/steep/ast/signature/gvar.rb +0 -17
- data/lib/steep/ast/signature/interface.rb +0 -31
- data/lib/steep/ast/signature/members.rb +0 -115
- data/lib/steep/ast/signature/module.rb +0 -21
- data/lib/steep/drivers/print_interface.rb +0 -94
- data/lib/steep/drivers/scaffold.rb +0 -321
- data/lib/steep/drivers/utils/each_signature.rb +0 -31
- data/lib/steep/interface/abstract.rb +0 -68
- data/lib/steep/interface/builder.rb +0 -637
- data/lib/steep/interface/instantiated.rb +0 -163
- data/lib/steep/interface/ivar_chain.rb +0 -26
- data/lib/steep/parser.y +0 -1278
- data/lib/steep/project/listener.rb +0 -53
- data/smoke/class/a.rbi +0 -24
- data/smoke/class/d.rb +0 -9
- data/smoke/class/e.rb +0 -12
- data/smoke/class/i.rbi +0 -9
- data/smoke/hash/e.rbi +0 -3
- data/smoke/hello/hello.rbi +0 -7
- data/smoke/implements/a.rbi +0 -6
- data/smoke/initialize/a.rbi +0 -3
- data/smoke/module/a.rbi +0 -16
- data/smoke/self/a.rbi +0 -4
- data/smoke/super/a.rbi +0 -10
- data/stdlib/builtin.rbi +0 -787
@@ -1,321 +0,0 @@
|
|
1
|
-
module Steep
|
2
|
-
module Drivers
|
3
|
-
class Scaffold
|
4
|
-
attr_reader :source_paths
|
5
|
-
attr_reader :stdout
|
6
|
-
attr_reader :stderr
|
7
|
-
attr_reader :labeling
|
8
|
-
|
9
|
-
include Utils::EachSignature
|
10
|
-
|
11
|
-
def initialize(source_paths:, stdout:, stderr:)
|
12
|
-
@source_paths = source_paths
|
13
|
-
@stdout = stdout
|
14
|
-
@stderr = stderr
|
15
|
-
end
|
16
|
-
|
17
|
-
def run
|
18
|
-
source_paths.each do |path|
|
19
|
-
each_file_in_path(".rb", path) do |file_path|
|
20
|
-
file = Project::SourceFile.new(path: file_path, options: Project::Options.new)
|
21
|
-
file.content = file_path.read
|
22
|
-
file.parse
|
23
|
-
Generator.new(source: file.source, stderr: stderr).write(io: stdout)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
0
|
27
|
-
end
|
28
|
-
|
29
|
-
class Generator
|
30
|
-
class Module
|
31
|
-
attr_reader :name
|
32
|
-
attr_reader :methods
|
33
|
-
attr_reader :singleton_methods
|
34
|
-
attr_reader :ivars
|
35
|
-
attr_reader :kind
|
36
|
-
|
37
|
-
def initialize(name:, kind:)
|
38
|
-
@kind = kind
|
39
|
-
@name = name
|
40
|
-
@ivars = {}
|
41
|
-
@methods = {}
|
42
|
-
@singleton_methods = {}
|
43
|
-
end
|
44
|
-
|
45
|
-
def class?
|
46
|
-
kind == :class
|
47
|
-
end
|
48
|
-
|
49
|
-
def module?
|
50
|
-
kind == :module
|
51
|
-
end
|
52
|
-
|
53
|
-
attr_accessor :has_subclass
|
54
|
-
|
55
|
-
def namespace_class?
|
56
|
-
has_subclass && methods.empty? && singleton_methods.empty?
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
attr_reader :source
|
61
|
-
attr_reader :modules
|
62
|
-
attr_reader :constants
|
63
|
-
attr_reader :stderr
|
64
|
-
|
65
|
-
def initialize(source:, stderr:)
|
66
|
-
@source = source
|
67
|
-
@stderr = stderr
|
68
|
-
@modules = []
|
69
|
-
@constants = {}
|
70
|
-
end
|
71
|
-
|
72
|
-
def write(io:)
|
73
|
-
generate(source.node, current_path: [])
|
74
|
-
|
75
|
-
modules.each do |mod|
|
76
|
-
unless mod.namespace_class?
|
77
|
-
io.puts "#{mod.kind} #{mod.name}"
|
78
|
-
|
79
|
-
mod.ivars.each do |name, type|
|
80
|
-
io.puts " #{name}: #{type}"
|
81
|
-
end
|
82
|
-
|
83
|
-
mod.methods.each do |name, type|
|
84
|
-
io.puts " def #{name}: #{type}"
|
85
|
-
end
|
86
|
-
|
87
|
-
mod.singleton_methods.each do |name, type|
|
88
|
-
io.puts " def self.#{name}: #{type}"
|
89
|
-
end
|
90
|
-
|
91
|
-
io.puts "end"
|
92
|
-
io.puts
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
constants.each do |name, ty|
|
97
|
-
io.puts "#{name}: #{ty}"
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
def module_name(name)
|
102
|
-
if name.type == :const
|
103
|
-
prefix = name.children[0]
|
104
|
-
if prefix
|
105
|
-
"#{module_name(prefix)}::#{name.children[1]}"
|
106
|
-
else
|
107
|
-
name.children[1].to_s
|
108
|
-
end
|
109
|
-
else
|
110
|
-
stderr.puts "Unexpected node for class name: #{name}"
|
111
|
-
return "____"
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
def full_name(current_path, name)
|
116
|
-
(current_path + [name]).join("::")
|
117
|
-
end
|
118
|
-
|
119
|
-
def generate(node, current_path:, current_module: nil, is_instance_method: false)
|
120
|
-
case node.type
|
121
|
-
when :module
|
122
|
-
name = module_name(node.children[0])
|
123
|
-
mod = Module.new(name: full_name(current_path, name), kind: :module)
|
124
|
-
modules << mod
|
125
|
-
|
126
|
-
if node.children[1]
|
127
|
-
generate(node.children[1],
|
128
|
-
current_path: current_path + [name],
|
129
|
-
current_module: mod)
|
130
|
-
end
|
131
|
-
|
132
|
-
if current_module
|
133
|
-
current_module.has_subclass = true
|
134
|
-
end
|
135
|
-
|
136
|
-
when :class
|
137
|
-
name = module_name(node.children[0])
|
138
|
-
klass = Module.new(name: full_name(current_path, name), kind: :class)
|
139
|
-
modules << klass
|
140
|
-
|
141
|
-
if node.children[2]
|
142
|
-
generate(node.children[2],
|
143
|
-
current_path: current_path + [name],
|
144
|
-
current_module: klass)
|
145
|
-
end
|
146
|
-
|
147
|
-
if current_module
|
148
|
-
current_module.has_subclass = true
|
149
|
-
end
|
150
|
-
|
151
|
-
when :def
|
152
|
-
name, args, body = node.children
|
153
|
-
|
154
|
-
if current_module
|
155
|
-
current_module.methods[name] = "(#{arg_types(args)}) -> #{guess_type(body)}"
|
156
|
-
end
|
157
|
-
|
158
|
-
if body
|
159
|
-
generate(body,
|
160
|
-
current_path: current_path,
|
161
|
-
current_module: current_module,
|
162
|
-
is_instance_method: true)
|
163
|
-
end
|
164
|
-
|
165
|
-
when :ivar, :ivasgn
|
166
|
-
name = node.children[0]
|
167
|
-
|
168
|
-
if current_module && is_instance_method
|
169
|
-
current_module.ivars[name] = guess_type(node.children[1])
|
170
|
-
end
|
171
|
-
|
172
|
-
each_child_node(node) do |child|
|
173
|
-
generate(child,
|
174
|
-
current_path: current_path,
|
175
|
-
current_module: current_module,
|
176
|
-
is_instance_method: is_instance_method)
|
177
|
-
end
|
178
|
-
|
179
|
-
when :defs
|
180
|
-
if node.children[0].type == :self
|
181
|
-
_, name, args, body = node.children
|
182
|
-
|
183
|
-
if current_module
|
184
|
-
current_module.singleton_methods[name] = "(#{arg_types(args)}) -> #{guess_type(body)}"
|
185
|
-
end
|
186
|
-
|
187
|
-
if body
|
188
|
-
generate(body,
|
189
|
-
current_path: current_path,
|
190
|
-
current_module: current_module,
|
191
|
-
is_instance_method: false)
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
when :casgn
|
196
|
-
if node.children[0]
|
197
|
-
stderr.puts "Unexpected casgn: #{node}, #{node.loc.line}"
|
198
|
-
end
|
199
|
-
|
200
|
-
constants[full_name(current_path, node.children[1])] = guess_type(node.children[2])
|
201
|
-
|
202
|
-
if node.children[2]
|
203
|
-
generate(node.children[2],
|
204
|
-
current_path: current_path,
|
205
|
-
current_module: current_module,
|
206
|
-
is_instance_method: is_instance_method)
|
207
|
-
end
|
208
|
-
|
209
|
-
else
|
210
|
-
each_child_node(node) do |child|
|
211
|
-
generate(child, current_path: current_path, current_module: current_module, is_instance_method: is_instance_method)
|
212
|
-
end
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
def guess_type(node)
|
217
|
-
return "any" unless node
|
218
|
-
case node.type
|
219
|
-
when :false, :true
|
220
|
-
"bool"
|
221
|
-
when :int
|
222
|
-
"Integer"
|
223
|
-
when :float
|
224
|
-
"Float"
|
225
|
-
when :complex
|
226
|
-
"Complex"
|
227
|
-
when :rational
|
228
|
-
"Rational"
|
229
|
-
when :str, :dstr, :xstr
|
230
|
-
"String"
|
231
|
-
when :sym, :dsym
|
232
|
-
"Symbol"
|
233
|
-
when :regexp
|
234
|
-
"Regexp"
|
235
|
-
when :array
|
236
|
-
"Array<any>"
|
237
|
-
when :hash
|
238
|
-
"Hash<any, any>"
|
239
|
-
when :irange, :erange
|
240
|
-
"Range<any>"
|
241
|
-
when :lvasgn, :ivasgn, :cvasgn, :gvasgn, :casgn
|
242
|
-
guess_type(node.children.last)
|
243
|
-
when :send
|
244
|
-
if node.children[1] == :[]=
|
245
|
-
guess_type(node.children.last)
|
246
|
-
else
|
247
|
-
"any"
|
248
|
-
end
|
249
|
-
when :begin
|
250
|
-
# should support shortcut return?
|
251
|
-
guess_type(node.children.last)
|
252
|
-
when :return
|
253
|
-
children = node.children
|
254
|
-
if children.size == 1
|
255
|
-
guess_type(node.children.last)
|
256
|
-
else
|
257
|
-
"Array<any>" # or Tuple or any?
|
258
|
-
end
|
259
|
-
when :if
|
260
|
-
children = node.children
|
261
|
-
if children[2]
|
262
|
-
ty1 = guess_type(children[1])
|
263
|
-
ty2 = guess_type(children[2])
|
264
|
-
if ty1 == ty2
|
265
|
-
ty1
|
266
|
-
else
|
267
|
-
"any"
|
268
|
-
end
|
269
|
-
else
|
270
|
-
"void" # assuming no-else if statement implies void
|
271
|
-
end
|
272
|
-
when :while, :until, :while_post, :until_post, :for
|
273
|
-
"void"
|
274
|
-
when :case
|
275
|
-
children = node.children
|
276
|
-
if children.last
|
277
|
-
ty = guess_type(children.last)
|
278
|
-
children[1..-2].each do |child|
|
279
|
-
return "any" if ty != guess_type(child.children.last)
|
280
|
-
end
|
281
|
-
ty
|
282
|
-
else
|
283
|
-
"any"
|
284
|
-
end
|
285
|
-
when :masgn
|
286
|
-
"void" # assuming masgn implies void
|
287
|
-
else
|
288
|
-
"any"
|
289
|
-
end
|
290
|
-
end
|
291
|
-
|
292
|
-
def each_child_node(node, &block)
|
293
|
-
node.children.each do |child|
|
294
|
-
if child.is_a?(::AST::Node)
|
295
|
-
yield child
|
296
|
-
end
|
297
|
-
end
|
298
|
-
end
|
299
|
-
|
300
|
-
def arg_types(args)
|
301
|
-
args.children.map do |arg|
|
302
|
-
case arg.type
|
303
|
-
when :arg
|
304
|
-
"any"
|
305
|
-
when :optarg
|
306
|
-
"?#{guess_type(arg.children[1])}"
|
307
|
-
when :restarg
|
308
|
-
"*any"
|
309
|
-
when :kwarg
|
310
|
-
"#{arg.children.first.name}: any"
|
311
|
-
when :kwoptarg
|
312
|
-
"?#{arg.children.first.name}: #{guess_type(arg.children[1])}"
|
313
|
-
when :kwrestarg
|
314
|
-
"**any"
|
315
|
-
end
|
316
|
-
end.compact.join(", ")
|
317
|
-
end
|
318
|
-
end
|
319
|
-
end
|
320
|
-
end
|
321
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
module Steep
|
2
|
-
module Drivers
|
3
|
-
module Utils
|
4
|
-
module EachSignature
|
5
|
-
def each_file_in_path(suffix, path)
|
6
|
-
if path.file?
|
7
|
-
yield path
|
8
|
-
end
|
9
|
-
|
10
|
-
if path.directory?
|
11
|
-
each_file_in_dir(suffix, path) do |file|
|
12
|
-
yield file
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def each_file_in_dir(suffix, path, &block)
|
18
|
-
path.children.each do |child|
|
19
|
-
if child.directory?
|
20
|
-
each_file_in_dir(suffix, child, &block)
|
21
|
-
end
|
22
|
-
|
23
|
-
if child.file? && suffix == child.extname
|
24
|
-
yield child
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,68 +0,0 @@
|
|
1
|
-
module Steep
|
2
|
-
module Interface
|
3
|
-
class Abstract
|
4
|
-
attr_reader :name
|
5
|
-
attr_reader :kind
|
6
|
-
attr_reader :params
|
7
|
-
attr_reader :methods
|
8
|
-
attr_reader :supers
|
9
|
-
attr_reader :ivar_chains
|
10
|
-
|
11
|
-
def initialize(name:, params:, methods:, supers:, ivar_chains:)
|
12
|
-
@name = name
|
13
|
-
@params = params
|
14
|
-
@methods = methods
|
15
|
-
@supers = supers
|
16
|
-
@ivar_chains = ivar_chains
|
17
|
-
end
|
18
|
-
|
19
|
-
def ivars
|
20
|
-
@ivars ||= ivar_chains.transform_values(&:type)
|
21
|
-
end
|
22
|
-
|
23
|
-
def ==(other)
|
24
|
-
other.is_a?(self.class) &&
|
25
|
-
other.name == name &&
|
26
|
-
other.params == params &&
|
27
|
-
other.methods == methods &&
|
28
|
-
other.supers == supers &&
|
29
|
-
other.ivars == ivars
|
30
|
-
end
|
31
|
-
|
32
|
-
def instantiate(type:, args:, instance_type:, module_type:)
|
33
|
-
Steep.logger.debug("type=#{type}, self=#{name}, args=#{args}, params=#{params}")
|
34
|
-
subst = Substitution.build(params, args, instance_type: instance_type, module_type: module_type, self_type: type)
|
35
|
-
|
36
|
-
Instantiated.new(
|
37
|
-
type: type,
|
38
|
-
methods: methods.transform_values {|method| method.subst(subst) },
|
39
|
-
ivar_chains: ivar_chains.transform_values {|chain| chain.subst(subst) }
|
40
|
-
)
|
41
|
-
end
|
42
|
-
|
43
|
-
def without_private(option)
|
44
|
-
if option
|
45
|
-
self.class.new(
|
46
|
-
name: name,
|
47
|
-
params: params,
|
48
|
-
methods: methods.reject {|_, method| method.private? },
|
49
|
-
supers: supers,
|
50
|
-
ivar_chains: ivar_chains
|
51
|
-
)
|
52
|
-
else
|
53
|
-
self
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def without_initialize
|
58
|
-
self.class.new(
|
59
|
-
name: name,
|
60
|
-
params: params,
|
61
|
-
methods: methods.reject {|_, method| method.name == :initialize },
|
62
|
-
supers: supers,
|
63
|
-
ivar_chains: ivar_chains
|
64
|
-
)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
@@ -1,637 +0,0 @@
|
|
1
|
-
module Steep
|
2
|
-
module Interface
|
3
|
-
class Builder
|
4
|
-
class RecursiveDefinitionError < StandardError
|
5
|
-
attr_reader :chain
|
6
|
-
|
7
|
-
def initialize(type_name)
|
8
|
-
@chain = [type_name].compact
|
9
|
-
super "Recursive inheritance/mixin"
|
10
|
-
end
|
11
|
-
|
12
|
-
def to_s
|
13
|
-
super + " #{chain.join(" ~> ")}"
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
attr_reader :signatures
|
18
|
-
attr_reader :class_cache
|
19
|
-
attr_reader :module_cache
|
20
|
-
attr_reader :instance_cache
|
21
|
-
attr_reader :interface_cache
|
22
|
-
|
23
|
-
def initialize(signatures:)
|
24
|
-
@signatures = signatures
|
25
|
-
@class_cache = {}
|
26
|
-
@module_cache = {}
|
27
|
-
@instance_cache = {}
|
28
|
-
@interface_cache = {}
|
29
|
-
end
|
30
|
-
|
31
|
-
def absolute_type(type, current:)
|
32
|
-
case type
|
33
|
-
when AST::Types::Name::Instance
|
34
|
-
signature = signatures.find_class_or_module(type.name, current_module: current)
|
35
|
-
AST::Types::Name::Instance.new(
|
36
|
-
name: signature.name,
|
37
|
-
args: type.args.map {|arg| absolute_type(arg, current: current) },
|
38
|
-
location: type.location
|
39
|
-
)
|
40
|
-
when AST::Types::Name::Class
|
41
|
-
signature = signatures.find_class(type.name, current_module: current)
|
42
|
-
AST::Types::Name::Class.new(
|
43
|
-
name: signature.name,
|
44
|
-
constructor: type.constructor,
|
45
|
-
location: type.location
|
46
|
-
)
|
47
|
-
when AST::Types::Name::Module
|
48
|
-
signature = signatures.find_class_or_module(type.name, current_module: current)
|
49
|
-
AST::Types::Name::Module.new(
|
50
|
-
name: signature.name,
|
51
|
-
location: type.location
|
52
|
-
)
|
53
|
-
when AST::Types::Name::Interface
|
54
|
-
signature = signatures.find_interface(type.name, namespace: current)
|
55
|
-
AST::Types::Name::Interface.new(
|
56
|
-
name: signature.name,
|
57
|
-
args: type.args.map {|arg| absolute_type(arg, current: current) },
|
58
|
-
location: type.location
|
59
|
-
)
|
60
|
-
when AST::Types::Name::Alias
|
61
|
-
signature = signatures.find_alias(type.name, namespace: current)
|
62
|
-
AST::Types::Name::Alias.new(
|
63
|
-
name: signature.name,
|
64
|
-
args: type.args.map {|arg| absolute_type(arg, current: current) },
|
65
|
-
location: type.location
|
66
|
-
)
|
67
|
-
when AST::Types::Union
|
68
|
-
AST::Types::Union.build(
|
69
|
-
types: type.types.map {|ty| absolute_type(ty, current: current) },
|
70
|
-
location: type.location
|
71
|
-
)
|
72
|
-
when AST::Types::Intersection
|
73
|
-
AST::Types::Intersection.build(
|
74
|
-
types: type.types.map {|ty| absolute_type(ty, current: current) },
|
75
|
-
location: type.location
|
76
|
-
)
|
77
|
-
when AST::Types::Tuple
|
78
|
-
AST::Types::Tuple.new(
|
79
|
-
types: type.types.map {|ty| absolute_type(ty, current:current) },
|
80
|
-
location: type.location
|
81
|
-
)
|
82
|
-
when AST::Types::Proc
|
83
|
-
AST::Types::Proc.new(
|
84
|
-
params: type.params.map_type {|ty| absolute_type(ty, current: current) },
|
85
|
-
return_type: absolute_type(type.return_type, current: current),
|
86
|
-
location: type.location
|
87
|
-
)
|
88
|
-
when AST::Types::Record
|
89
|
-
AST::Types::Record.new(
|
90
|
-
elements: type.elements.transform_values {|ty| absolute_type(ty, current: current) },
|
91
|
-
location: type.location
|
92
|
-
)
|
93
|
-
else
|
94
|
-
type
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
def cache_interface(cache, key:, &block)
|
99
|
-
cached = cache[key]
|
100
|
-
|
101
|
-
case cached
|
102
|
-
when nil
|
103
|
-
cache[key] = key
|
104
|
-
cache[key] = yield
|
105
|
-
when key
|
106
|
-
raise RecursiveDefinitionError, key
|
107
|
-
else
|
108
|
-
cached
|
109
|
-
end
|
110
|
-
rescue RecursiveDefinitionError => exn
|
111
|
-
cache.delete key
|
112
|
-
raise exn
|
113
|
-
end
|
114
|
-
|
115
|
-
def assert_absolute_name!(name)
|
116
|
-
raise "Name should be absolute: #{name}" unless name.absolute?
|
117
|
-
end
|
118
|
-
|
119
|
-
def build_class(module_name, constructor:)
|
120
|
-
assert_absolute_name! module_name
|
121
|
-
signature = signatures.find_class(module_name, current_module: AST::Namespace.root)
|
122
|
-
cache_interface(class_cache, key: [signature.name, !!constructor]) do
|
123
|
-
class_to_interface(signature, constructor: constructor)
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
def build_module(module_name)
|
128
|
-
assert_absolute_name! module_name
|
129
|
-
signature = signatures.find_module(module_name, current_module: AST::Namespace.root)
|
130
|
-
cache_interface(module_cache, key: signature.name) do
|
131
|
-
module_to_interface(signature)
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
def build_instance(module_name)
|
136
|
-
assert_absolute_name! module_name
|
137
|
-
signature = signatures.find_class_or_module(module_name, current_module: AST::Namespace.root)
|
138
|
-
cache_interface(instance_cache, key: signature.name) do
|
139
|
-
instance_to_interface(signature)
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
def build_interface(interface_name)
|
144
|
-
signature = signatures.find_interface(interface_name)
|
145
|
-
cache_interface(interface_cache, key: [signature.name]) do
|
146
|
-
interface_to_interface(nil, signature)
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
def merge_mixin(interface, args, methods:, ivars:, supers:, current:)
|
151
|
-
supers.push(*interface.supers)
|
152
|
-
|
153
|
-
instantiated = interface.instantiate(
|
154
|
-
type: AST::Types::Self.new,
|
155
|
-
args: args,
|
156
|
-
instance_type: AST::Types::Instance.new,
|
157
|
-
module_type: AST::Types::Class.new
|
158
|
-
)
|
159
|
-
|
160
|
-
methods.merge!(instantiated.methods) do |_, super_method, new_method|
|
161
|
-
if super_method.include_in_chain?(new_method)
|
162
|
-
super_method
|
163
|
-
else
|
164
|
-
new_method.with_super(super_method)
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
merge_ivars ivars, instantiated.ivars
|
169
|
-
end
|
170
|
-
|
171
|
-
def add_method(type_name, method, methods:, extra_attributes: [], current:)
|
172
|
-
super_method = methods[method.name]
|
173
|
-
new_method = Method.new(
|
174
|
-
type_name: type_name,
|
175
|
-
name: method.name,
|
176
|
-
types: method.types.flat_map do |method_type|
|
177
|
-
case method_type
|
178
|
-
when AST::MethodType
|
179
|
-
[method_type_to_method_type(method_type, current: current)]
|
180
|
-
when AST::MethodType::Super
|
181
|
-
if super_method
|
182
|
-
super_method.types
|
183
|
-
else
|
184
|
-
Steep.logger.error "`super` specified in method type, but cannot find super method of `#{method.name}` in `#{type_name}` (#{method.location.name || "-"}:#{method.location})"
|
185
|
-
[]
|
186
|
-
end
|
187
|
-
end
|
188
|
-
end,
|
189
|
-
super_method: super_method,
|
190
|
-
attributes: method.attributes + extra_attributes
|
191
|
-
)
|
192
|
-
|
193
|
-
methods[method.name] = if super_method&.include_in_chain?(new_method)
|
194
|
-
super_method
|
195
|
-
else
|
196
|
-
new_method
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
def class_to_interface(sig, constructor:)
|
201
|
-
module_name = sig.name
|
202
|
-
namespace = module_name.namespace.append(module_name.name)
|
203
|
-
|
204
|
-
supers = []
|
205
|
-
methods = {
|
206
|
-
new: Method.new(
|
207
|
-
type_name: Names::Module.parse(name: "__Builtin__"),
|
208
|
-
name: :new,
|
209
|
-
types: [
|
210
|
-
MethodType.new(type_params: [],
|
211
|
-
params: Params.empty,
|
212
|
-
block: nil,
|
213
|
-
return_type: AST::Types::Instance.new,
|
214
|
-
location: nil
|
215
|
-
)
|
216
|
-
],
|
217
|
-
super_method: nil,
|
218
|
-
attributes: [:incompatible]
|
219
|
-
)
|
220
|
-
}
|
221
|
-
|
222
|
-
klass = build_instance(AST::Builtin::Class.module_name)
|
223
|
-
instantiated = klass.instantiate(
|
224
|
-
type: AST::Types::Self.new,
|
225
|
-
args: [],
|
226
|
-
instance_type: AST::Types::Instance.new,
|
227
|
-
module_type: AST::Types::Class.new
|
228
|
-
)
|
229
|
-
methods.merge!(instantiated.methods)
|
230
|
-
|
231
|
-
unless module_name == AST::Builtin::BasicObject.module_name
|
232
|
-
super_class_name = sig.super_class&.name&.yield_self {|name| signatures.find_class(name, current_module: namespace).name } || AST::Builtin::Object.module_name
|
233
|
-
class_interface = build_class(super_class_name, constructor: constructor)
|
234
|
-
merge_mixin(class_interface, [], methods: methods, ivars: {}, supers: supers, current: namespace)
|
235
|
-
end
|
236
|
-
|
237
|
-
sig.members.each do |member|
|
238
|
-
case member
|
239
|
-
when AST::Signature::Members::Include
|
240
|
-
member_name = signatures.find_module(member.name, current_module: namespace).name
|
241
|
-
build_module(member_name).yield_self do |module_interface|
|
242
|
-
merge_mixin(module_interface,
|
243
|
-
[],
|
244
|
-
methods: methods,
|
245
|
-
supers: supers,
|
246
|
-
ivars: {},
|
247
|
-
current: namespace)
|
248
|
-
end
|
249
|
-
when AST::Signature::Members::Extend
|
250
|
-
member_name = signatures.find_module(member.name, current_module: namespace).name
|
251
|
-
build_instance(member_name).yield_self do |module_interface|
|
252
|
-
merge_mixin(module_interface,
|
253
|
-
member.args.map {|type| absolute_type(type, current: namespace) },
|
254
|
-
methods: methods,
|
255
|
-
ivars: {},
|
256
|
-
supers: supers,
|
257
|
-
current: namespace)
|
258
|
-
end
|
259
|
-
end
|
260
|
-
end
|
261
|
-
|
262
|
-
sig.members.each do |member|
|
263
|
-
case member
|
264
|
-
when AST::Signature::Members::Method
|
265
|
-
case
|
266
|
-
when member.module_method?
|
267
|
-
add_method(module_name, member, methods: methods, current: namespace)
|
268
|
-
when member.instance_method? && member.name == :initialize
|
269
|
-
if constructor
|
270
|
-
methods[:new] = Method.new(
|
271
|
-
type_name: module_name,
|
272
|
-
name: :new,
|
273
|
-
types: member.types.map do |method_type_sig|
|
274
|
-
method_type = method_type_to_method_type(method_type_sig, current: namespace).with(return_type: AST::Types::Instance.new)
|
275
|
-
args = (sig.params&.variables || []) + method_type.type_params
|
276
|
-
|
277
|
-
method_type.with(
|
278
|
-
type_params: args,
|
279
|
-
return_type: AST::Types::Instance.new
|
280
|
-
)
|
281
|
-
end,
|
282
|
-
super_method: nil,
|
283
|
-
attributes: [:incompatible]
|
284
|
-
)
|
285
|
-
end
|
286
|
-
end
|
287
|
-
end
|
288
|
-
end
|
289
|
-
|
290
|
-
signatures.find_extensions(sig.name).each do |ext|
|
291
|
-
ext.members.each do |member|
|
292
|
-
case member
|
293
|
-
when AST::Signature::Members::Method
|
294
|
-
if member.module_method?
|
295
|
-
add_method(module_name, member, methods: methods, current: namespace)
|
296
|
-
end
|
297
|
-
end
|
298
|
-
end
|
299
|
-
end
|
300
|
-
|
301
|
-
if methods[:new]&.type_name == AST::Builtin::Class.module_name
|
302
|
-
new_types = [MethodType.new(type_params: [],
|
303
|
-
params: Params.empty,
|
304
|
-
block: nil,
|
305
|
-
return_type: AST::Types::Instance.new,
|
306
|
-
location: nil)]
|
307
|
-
methods[:new] = methods[:new].with_types(new_types)
|
308
|
-
end
|
309
|
-
|
310
|
-
unless constructor
|
311
|
-
methods.delete(:new)
|
312
|
-
end
|
313
|
-
|
314
|
-
Abstract.new(
|
315
|
-
name: module_name,
|
316
|
-
params: [],
|
317
|
-
methods: methods,
|
318
|
-
supers: supers,
|
319
|
-
ivar_chains: {}
|
320
|
-
)
|
321
|
-
end
|
322
|
-
|
323
|
-
def module_to_interface(sig)
|
324
|
-
module_name = sig.name
|
325
|
-
namespace = module_name.namespace.append(module_name.name)
|
326
|
-
|
327
|
-
supers = [sig.self_type].compact.map {|type| absolute_type(type, current: namespace) }
|
328
|
-
methods = {}
|
329
|
-
ivar_chains = {}
|
330
|
-
|
331
|
-
module_instance = build_instance(AST::Builtin::Module.module_name)
|
332
|
-
instantiated = module_instance.instantiate(
|
333
|
-
type: AST::Types::Self.new,
|
334
|
-
args: [],
|
335
|
-
instance_type: AST::Types::Instance.new,
|
336
|
-
module_type: AST::Types::Class.new
|
337
|
-
)
|
338
|
-
methods.merge!(instantiated.methods)
|
339
|
-
|
340
|
-
sig.members.each do |member|
|
341
|
-
case member
|
342
|
-
when AST::Signature::Members::Include
|
343
|
-
member_name = signatures.find_module(member.name, current_module: namespace).name
|
344
|
-
build_module(member_name).yield_self do |module_interface|
|
345
|
-
merge_mixin(module_interface,
|
346
|
-
member.args.map {|type| absolute_type(type, current: namespace) },
|
347
|
-
methods: methods,
|
348
|
-
ivars: ivar_chains,
|
349
|
-
supers: supers,
|
350
|
-
current: namespace)
|
351
|
-
end
|
352
|
-
when AST::Signature::Members::Extend
|
353
|
-
member_name = signatures.find_module(member.name, current_module: namespace).name
|
354
|
-
build_instance(member_name).yield_self do |module_interface|
|
355
|
-
merge_mixin(module_interface,
|
356
|
-
member.args.map {|type| absolute_type(type, current: namespace) },
|
357
|
-
methods: methods,
|
358
|
-
ivars: ivar_chains,
|
359
|
-
supers: supers,
|
360
|
-
current: namespace)
|
361
|
-
|
362
|
-
end
|
363
|
-
end
|
364
|
-
end
|
365
|
-
|
366
|
-
sig.members.each do |member|
|
367
|
-
case member
|
368
|
-
when AST::Signature::Members::Method
|
369
|
-
if member.module_method?
|
370
|
-
add_method(module_name, member, methods: methods, current: namespace)
|
371
|
-
end
|
372
|
-
when AST::Signature::Members::Ivar
|
373
|
-
merge_ivars(ivar_chains,
|
374
|
-
{ member.name => absolute_type(member.type, current: namespace) })
|
375
|
-
when AST::Signature::Members::Attr
|
376
|
-
merge_attribute(sig, ivar_chains, methods, module_name, member)
|
377
|
-
end
|
378
|
-
end
|
379
|
-
|
380
|
-
signatures.find_extensions(module_name).each do |ext|
|
381
|
-
ext.members.each do |member|
|
382
|
-
case member
|
383
|
-
when AST::Signature::Members::Method
|
384
|
-
if member.module_method?
|
385
|
-
add_method(module_name, member, methods: methods, current: namespace)
|
386
|
-
end
|
387
|
-
end
|
388
|
-
end
|
389
|
-
end
|
390
|
-
|
391
|
-
Abstract.new(
|
392
|
-
name: module_name,
|
393
|
-
params: [],
|
394
|
-
methods: methods,
|
395
|
-
supers: supers,
|
396
|
-
ivar_chains: ivar_chains
|
397
|
-
)
|
398
|
-
end
|
399
|
-
|
400
|
-
def instance_to_interface(sig)
|
401
|
-
module_name = sig.name
|
402
|
-
namespace = module_name.namespace.append(module_name.name)
|
403
|
-
|
404
|
-
params = sig.params&.variables || []
|
405
|
-
supers = []
|
406
|
-
methods = {}
|
407
|
-
ivar_chains = {}
|
408
|
-
|
409
|
-
if sig.is_a?(AST::Signature::Class)
|
410
|
-
unless sig.name == AST::Builtin::BasicObject.module_name
|
411
|
-
super_class_name = sig.super_class&.name || AST::Builtin::Object.module_name
|
412
|
-
if super_class_name.relative?
|
413
|
-
super_class_name = signatures.find_class(super_class_name, current_module: namespace).name
|
414
|
-
end
|
415
|
-
super_class_interface = build_instance(super_class_name)
|
416
|
-
|
417
|
-
supers.push(*super_class_interface.supers)
|
418
|
-
instantiated = super_class_interface.instantiate(
|
419
|
-
type: AST::Types::Self.new,
|
420
|
-
args: (sig.super_class&.args || []).map {|type| absolute_type(type, current: namespace) },
|
421
|
-
instance_type: AST::Types::Instance.new,
|
422
|
-
module_type: AST::Types::Class.new
|
423
|
-
)
|
424
|
-
|
425
|
-
methods.merge!(instantiated.methods)
|
426
|
-
merge_ivars(ivar_chains, instantiated.ivars)
|
427
|
-
end
|
428
|
-
end
|
429
|
-
|
430
|
-
if sig.is_a?(AST::Signature::Module)
|
431
|
-
if sig.self_type
|
432
|
-
supers << absolute_type(sig.self_type, current: namespace)
|
433
|
-
end
|
434
|
-
end
|
435
|
-
|
436
|
-
sig.members.each do |member|
|
437
|
-
case member
|
438
|
-
when AST::Signature::Members::Include
|
439
|
-
member_name = signatures.find_module(member.name, current_module: namespace).name
|
440
|
-
build_instance(member_name).yield_self do |module_interface|
|
441
|
-
merge_mixin(module_interface,
|
442
|
-
member.args.map {|type| absolute_type(type, current: namespace) },
|
443
|
-
methods: methods,
|
444
|
-
ivars: ivar_chains,
|
445
|
-
supers: supers,
|
446
|
-
current: namespace)
|
447
|
-
end
|
448
|
-
end
|
449
|
-
end
|
450
|
-
|
451
|
-
sig.members.each do |member|
|
452
|
-
case member
|
453
|
-
when AST::Signature::Members::Method
|
454
|
-
if member.instance_method?
|
455
|
-
extra_attrs = member.name == :initialize ? [:incompatible, :private] : []
|
456
|
-
add_method(module_name, member, methods: methods, extra_attributes: extra_attrs, current: namespace)
|
457
|
-
end
|
458
|
-
when AST::Signature::Members::Ivar
|
459
|
-
merge_ivars(ivar_chains,
|
460
|
-
{ member.name => absolute_type(member.type, current: namespace) })
|
461
|
-
when AST::Signature::Members::Attr
|
462
|
-
merge_attribute(sig, ivar_chains, methods, module_name, member, current: namespace)
|
463
|
-
end
|
464
|
-
end
|
465
|
-
|
466
|
-
sig.members.each do |member|
|
467
|
-
case member
|
468
|
-
when AST::Signature::Members::MethodAlias
|
469
|
-
method = methods[member.original_name]
|
470
|
-
if method
|
471
|
-
methods[member.new_name] = Method.new(
|
472
|
-
type_name: module_name,
|
473
|
-
name: member.new_name,
|
474
|
-
types: method.types,
|
475
|
-
super_method: nil,
|
476
|
-
attributes: method.attributes
|
477
|
-
)
|
478
|
-
else
|
479
|
-
Steep.logger.error "Cannot alias find original method `#{member.original_name}` for `#{member.new_name}` in #{module_name} (#{member.location.name || '-'}:#{member.location})"
|
480
|
-
end
|
481
|
-
end
|
482
|
-
end
|
483
|
-
|
484
|
-
signatures.find_extensions(sig.name).each do |ext|
|
485
|
-
ext.members.each do |member|
|
486
|
-
case member
|
487
|
-
when AST::Signature::Members::Method
|
488
|
-
if member.instance_method?
|
489
|
-
add_method(module_name, member, methods: methods, current: namespace)
|
490
|
-
end
|
491
|
-
end
|
492
|
-
end
|
493
|
-
end
|
494
|
-
|
495
|
-
Abstract.new(
|
496
|
-
name: module_name,
|
497
|
-
params: params,
|
498
|
-
methods: methods,
|
499
|
-
supers: supers,
|
500
|
-
ivar_chains: ivar_chains
|
501
|
-
)
|
502
|
-
end
|
503
|
-
|
504
|
-
def merge_attribute(sig, ivar_chains, methods, type_name, member, current:)
|
505
|
-
if member.ivar != false
|
506
|
-
ivar_name = member.ivar || "@#{member.name}".to_sym
|
507
|
-
merge_ivars(ivar_chains,
|
508
|
-
{ ivar_name => absolute_type(member.type, current: current) })
|
509
|
-
end
|
510
|
-
|
511
|
-
reader_method = AST::Signature::Members::Method.new(
|
512
|
-
location: member.location,
|
513
|
-
name: member.name,
|
514
|
-
kind: :instance,
|
515
|
-
types: [
|
516
|
-
AST::MethodType.new(location: member.type.location,
|
517
|
-
type_params: nil,
|
518
|
-
params: nil,
|
519
|
-
block: nil,
|
520
|
-
return_type: member.type)
|
521
|
-
],
|
522
|
-
attributes: []
|
523
|
-
)
|
524
|
-
add_method(type_name, reader_method, methods: methods, current: current)
|
525
|
-
|
526
|
-
if member.accessor?
|
527
|
-
writer_method = AST::Signature::Members::Method.new(
|
528
|
-
location: member.location,
|
529
|
-
name: "#{member.name}=".to_sym,
|
530
|
-
kind: :instance,
|
531
|
-
types: [
|
532
|
-
AST::MethodType.new(location: member.type.location,
|
533
|
-
type_params: nil,
|
534
|
-
params: AST::MethodType::Params::Required.new(
|
535
|
-
location: member.type.location,
|
536
|
-
type: member.type
|
537
|
-
),
|
538
|
-
block: nil,
|
539
|
-
return_type: member.type)
|
540
|
-
],
|
541
|
-
attributes: []
|
542
|
-
)
|
543
|
-
add_method(type_name, writer_method, methods: methods, current: current)
|
544
|
-
end
|
545
|
-
end
|
546
|
-
|
547
|
-
def merge_ivars(dest, new_vars)
|
548
|
-
new_vars.each do |name, new_type|
|
549
|
-
dest[name] = IvarChain.new(type: new_type, parent: dest[name])
|
550
|
-
end
|
551
|
-
end
|
552
|
-
|
553
|
-
def interface_to_interface(_, sig)
|
554
|
-
type_name = sig.name
|
555
|
-
|
556
|
-
variables = sig.params&.variables || []
|
557
|
-
methods = sig.methods.each.with_object({}) do |method, methods|
|
558
|
-
methods[method.name] = Method.new(
|
559
|
-
type_name: type_name,
|
560
|
-
name: method.name,
|
561
|
-
types: method.types.map do |method_type|
|
562
|
-
method_type_to_method_type(method_type, current: type_name.namespace)
|
563
|
-
end,
|
564
|
-
super_method: nil,
|
565
|
-
attributes: []
|
566
|
-
)
|
567
|
-
end
|
568
|
-
|
569
|
-
Abstract.new(
|
570
|
-
name: type_name,
|
571
|
-
params: variables,
|
572
|
-
methods: methods,
|
573
|
-
supers: [],
|
574
|
-
ivar_chains: {}
|
575
|
-
)
|
576
|
-
end
|
577
|
-
|
578
|
-
def method_type_to_method_type(method_type, current:)
|
579
|
-
type_params = method_type.type_params&.variables || []
|
580
|
-
params = params_to_params(method_type.params, current: current)
|
581
|
-
block = method_type.block && Block.new(
|
582
|
-
type: AST::Types::Proc.new(
|
583
|
-
params: params_to_params(method_type.block.params, current: current),
|
584
|
-
return_type: absolute_type(method_type.block.return_type, current: current),
|
585
|
-
location: method_type.block.location,
|
586
|
-
),
|
587
|
-
optional: method_type.block.optional
|
588
|
-
)
|
589
|
-
|
590
|
-
MethodType.new(
|
591
|
-
type_params: type_params,
|
592
|
-
return_type: absolute_type(method_type.return_type, current: current),
|
593
|
-
block: block,
|
594
|
-
params: params,
|
595
|
-
location: method_type.location
|
596
|
-
)
|
597
|
-
end
|
598
|
-
|
599
|
-
def params_to_params(params, current:)
|
600
|
-
required = []
|
601
|
-
optional = []
|
602
|
-
rest = nil
|
603
|
-
required_keywords = {}
|
604
|
-
optional_keywords = {}
|
605
|
-
rest_keywords = nil
|
606
|
-
|
607
|
-
while params
|
608
|
-
case params
|
609
|
-
when AST::MethodType::Params::Required
|
610
|
-
required << absolute_type(params.type, current: current)
|
611
|
-
when AST::MethodType::Params::Optional
|
612
|
-
optional << absolute_type(params.type, current: current)
|
613
|
-
when AST::MethodType::Params::Rest
|
614
|
-
rest = absolute_type(params.type, current: current)
|
615
|
-
when AST::MethodType::Params::RequiredKeyword
|
616
|
-
required_keywords[params.name] = absolute_type(params.type, current: current)
|
617
|
-
when AST::MethodType::Params::OptionalKeyword
|
618
|
-
optional_keywords[params.name] = absolute_type(params.type, current: current)
|
619
|
-
when AST::MethodType::Params::RestKeyword
|
620
|
-
rest_keywords = absolute_type(params.type, current: current)
|
621
|
-
break
|
622
|
-
end
|
623
|
-
params = params.next_params
|
624
|
-
end
|
625
|
-
|
626
|
-
Params.new(
|
627
|
-
required: required,
|
628
|
-
optional: optional,
|
629
|
-
rest: rest,
|
630
|
-
required_keywords: required_keywords,
|
631
|
-
optional_keywords: optional_keywords,
|
632
|
-
rest_keywords: rest_keywords
|
633
|
-
)
|
634
|
-
end
|
635
|
-
end
|
636
|
-
end
|
637
|
-
end
|