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
@@ -0,0 +1,167 @@
|
|
1
|
+
module Steep
|
2
|
+
class AnnotationParser
|
3
|
+
VAR_NAME = /[a-z][A-Za-z0-9_]*/
|
4
|
+
METHOD_NAME = Regexp.union(
|
5
|
+
/[A-Za-z][A-Za-z0-9_]*[?!]?/
|
6
|
+
)
|
7
|
+
CONST_NAME = Regexp.union(
|
8
|
+
/(::)?([A-Z][A-Za-z0-9_]*::)*[A-Z][A-Za-z0-9_]*/
|
9
|
+
)
|
10
|
+
DYNAMIC_NAME = /(self\??\.)?#{METHOD_NAME}/
|
11
|
+
IVAR_NAME = /@[^:\s]+/
|
12
|
+
|
13
|
+
attr_reader :factory
|
14
|
+
|
15
|
+
def initialize(factory:)
|
16
|
+
@factory = factory
|
17
|
+
end
|
18
|
+
|
19
|
+
class SyntaxError < StandardError
|
20
|
+
attr_reader :source
|
21
|
+
attr_reader :location
|
22
|
+
|
23
|
+
def initialize(source:, location:, exn: nil)
|
24
|
+
@source = source
|
25
|
+
@location = location
|
26
|
+
super "Syntax error on annotation: `#{source}`, cause=#{exn.inspect}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
TYPE = /(?<type>.*)/
|
31
|
+
COLON = /\s*:\s*/
|
32
|
+
|
33
|
+
PARAM = /[A-Z][A-Za-z0-9_]*/
|
34
|
+
TYPE_PARAMS = /(\[(?<params>#{PARAM}(,\s*#{PARAM})*)\])?/
|
35
|
+
|
36
|
+
def parse_type(string)
|
37
|
+
factory.type(Ruby::Signature::Parser.parse_type(string))
|
38
|
+
end
|
39
|
+
|
40
|
+
# @type ${keyword} ${name}: ${type}
|
41
|
+
# Example: @type const Foo::Bar: String
|
42
|
+
# @type var xyzzy: Array[String]
|
43
|
+
def keyword_subject_type(keyword, name)
|
44
|
+
/@type\s+#{keyword}\s+(?<name>#{name})#{COLON}#{TYPE}/
|
45
|
+
end
|
46
|
+
|
47
|
+
# @type ${keyword}: ${type}
|
48
|
+
# Example: @type break: String
|
49
|
+
# @type self: Foo
|
50
|
+
def keyword_and_type(keyword)
|
51
|
+
/@type\s+#{keyword}#{COLON}#{TYPE}/
|
52
|
+
end
|
53
|
+
|
54
|
+
def parse(src, location:)
|
55
|
+
case src
|
56
|
+
when keyword_subject_type("var", VAR_NAME)
|
57
|
+
Regexp.last_match.yield_self do |match|
|
58
|
+
name = match[:name]
|
59
|
+
type = match[:type]
|
60
|
+
|
61
|
+
AST::Annotation::VarType.new(name: name.to_sym,
|
62
|
+
type: parse_type(type),
|
63
|
+
location: location)
|
64
|
+
end
|
65
|
+
|
66
|
+
when keyword_subject_type("method", METHOD_NAME)
|
67
|
+
Regexp.last_match.yield_self do |match|
|
68
|
+
name = match[:name]
|
69
|
+
type = match[:type]
|
70
|
+
|
71
|
+
method_type = factory.method_type(Ruby::Signature::Parser.parse_method_type(type), self_type: AST::Types::Self.new)
|
72
|
+
|
73
|
+
AST::Annotation::MethodType.new(name: name.to_sym,
|
74
|
+
type: method_type,
|
75
|
+
location: location)
|
76
|
+
end
|
77
|
+
|
78
|
+
when keyword_subject_type("const", CONST_NAME)
|
79
|
+
Regexp.last_match.yield_self do |match|
|
80
|
+
name = match[:name]
|
81
|
+
type = parse_type(match[:type])
|
82
|
+
|
83
|
+
AST::Annotation::ConstType.new(name: Names::Module.parse(name),
|
84
|
+
type: type,
|
85
|
+
location: location)
|
86
|
+
end
|
87
|
+
|
88
|
+
when keyword_subject_type("ivar", IVAR_NAME)
|
89
|
+
Regexp.last_match.yield_self do |match|
|
90
|
+
name = match[:name]
|
91
|
+
type = parse_type(match[:type])
|
92
|
+
|
93
|
+
AST::Annotation::IvarType.new(name: name.to_sym,
|
94
|
+
type: type,
|
95
|
+
location: location)
|
96
|
+
end
|
97
|
+
|
98
|
+
when keyword_and_type("return")
|
99
|
+
Regexp.last_match.yield_self do |match|
|
100
|
+
type = parse_type(match[:type])
|
101
|
+
AST::Annotation::ReturnType.new(type: type, location: location)
|
102
|
+
end
|
103
|
+
|
104
|
+
when keyword_and_type("block")
|
105
|
+
Regexp.last_match.yield_self do |match|
|
106
|
+
type = parse_type(match[:type])
|
107
|
+
AST::Annotation::BlockType.new(type: type, location: location)
|
108
|
+
end
|
109
|
+
|
110
|
+
when keyword_and_type("self")
|
111
|
+
Regexp.last_match.yield_self do |match|
|
112
|
+
type = parse_type(match[:type])
|
113
|
+
AST::Annotation::SelfType.new(type: type, location: location)
|
114
|
+
end
|
115
|
+
|
116
|
+
when keyword_and_type("instance")
|
117
|
+
Regexp.last_match.yield_self do |match|
|
118
|
+
type = parse_type(match[:type])
|
119
|
+
AST::Annotation::InstanceType.new(type: type, location: location)
|
120
|
+
end
|
121
|
+
|
122
|
+
when keyword_and_type("module")
|
123
|
+
Regexp.last_match.yield_self do |match|
|
124
|
+
type = parse_type(match[:type])
|
125
|
+
AST::Annotation::ModuleType.new(type: type, location: location)
|
126
|
+
end
|
127
|
+
|
128
|
+
when keyword_and_type("break")
|
129
|
+
Regexp.last_match.yield_self do |match|
|
130
|
+
type = parse_type(match[:type])
|
131
|
+
AST::Annotation::BreakType.new(type: type, location: location)
|
132
|
+
end
|
133
|
+
|
134
|
+
when /@dynamic\s+(?<names>(#{DYNAMIC_NAME}\s*,\s*)*#{DYNAMIC_NAME})/
|
135
|
+
Regexp.last_match.yield_self do |match|
|
136
|
+
names = match[:names].split(/\s*,\s*/)
|
137
|
+
|
138
|
+
AST::Annotation::Dynamic.new(
|
139
|
+
names: names.map {|name|
|
140
|
+
case name
|
141
|
+
when /^self\./
|
142
|
+
AST::Annotation::Dynamic::Name.new(name: name[5..].to_sym, kind: :module)
|
143
|
+
when /^self\?\./
|
144
|
+
AST::Annotation::Dynamic::Name.new(name: name[6..].to_sym, kind: :module_instance)
|
145
|
+
else
|
146
|
+
AST::Annotation::Dynamic::Name.new(name: name.to_sym, kind: :instance)
|
147
|
+
end
|
148
|
+
},
|
149
|
+
location: location
|
150
|
+
)
|
151
|
+
end
|
152
|
+
|
153
|
+
when /@implements\s+(?<name>#{CONST_NAME})#{TYPE_PARAMS}$/
|
154
|
+
Regexp.last_match.yield_self do |match|
|
155
|
+
type_name = Names::Module.parse(match[:name])
|
156
|
+
params = match[:params]&.yield_self {|params| params.split(/,/).map {|param| param.strip.to_sym } } || []
|
157
|
+
|
158
|
+
name = AST::Annotation::Implements::Module.new(name: type_name, args: params)
|
159
|
+
AST::Annotation::Implements.new(name: name, location: location)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
rescue Ruby::Signature::Parser::SyntaxError, Ruby::Signature::Parser::SemanticsError => exn
|
164
|
+
raise SyntaxError.new(source: src, location: location, exn: exn)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
@@ -3,7 +3,7 @@ module Steep
|
|
3
3
|
module Annotation
|
4
4
|
class Collection
|
5
5
|
attr_reader :annotations
|
6
|
-
attr_reader :
|
6
|
+
attr_reader :factory
|
7
7
|
attr_reader :current_module
|
8
8
|
|
9
9
|
attr_reader :var_type_annotations
|
@@ -19,9 +19,9 @@ module Steep
|
|
19
19
|
attr_reader :dynamic_annotations
|
20
20
|
attr_reader :break_type_annotation
|
21
21
|
|
22
|
-
def initialize(annotations:,
|
22
|
+
def initialize(annotations:, factory:, current_module:)
|
23
23
|
@annotations = annotations
|
24
|
-
@
|
24
|
+
@factory = factory
|
25
25
|
@current_module = current_module
|
26
26
|
|
27
27
|
@var_type_annotations = {}
|
@@ -64,7 +64,7 @@ module Steep
|
|
64
64
|
|
65
65
|
def absolute_type(type)
|
66
66
|
if type
|
67
|
-
|
67
|
+
factory.absolute_type(type, namespace: current_module)
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
@@ -81,7 +81,7 @@ module Steep
|
|
81
81
|
|
82
82
|
def method_type(name)
|
83
83
|
if (a = method_type_annotations[name])
|
84
|
-
|
84
|
+
a.type.map_type {|type| absolute_type(type) }
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
@@ -140,7 +140,7 @@ module Steep
|
|
140
140
|
end
|
141
141
|
|
142
142
|
def merge_block_annotations(annotations)
|
143
|
-
if annotations.current_module != current_module || annotations.
|
143
|
+
if annotations.current_module != current_module || annotations.factory != factory
|
144
144
|
raise "Cannot merge another annotation: self=#{self}, other=#{annotations}"
|
145
145
|
end
|
146
146
|
|
@@ -149,7 +149,7 @@ module Steep
|
|
149
149
|
end
|
150
150
|
|
151
151
|
self.class.new(annotations: retained_annotations + annotations.annotations,
|
152
|
-
|
152
|
+
factory: factory,
|
153
153
|
current_module: current_module)
|
154
154
|
end
|
155
155
|
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Steep
|
2
|
+
module AST
|
3
|
+
module Types
|
4
|
+
class Masked
|
5
|
+
attr_reader :location
|
6
|
+
attr_reader :type
|
7
|
+
attr_reader :mask
|
8
|
+
|
9
|
+
def initialize(type:, mask:, location:)
|
10
|
+
@type = type
|
11
|
+
@mask = mask
|
12
|
+
@location = location
|
13
|
+
end
|
14
|
+
|
15
|
+
def ==(other)
|
16
|
+
other.is_a?(Masked) &&
|
17
|
+
other.type == type &&
|
18
|
+
other.mask == mask
|
19
|
+
end
|
20
|
+
|
21
|
+
alias eql? ==
|
22
|
+
|
23
|
+
def hash
|
24
|
+
self.class.hash ^ type.hash ^ mask.hash
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_json(*a)
|
28
|
+
{ class: :masked,
|
29
|
+
type: type,
|
30
|
+
mask: mask,
|
31
|
+
location: location }.to_json(*a)
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_s(level = 0)
|
35
|
+
"masked(#{type}|#{mask})"
|
36
|
+
end
|
37
|
+
|
38
|
+
def free_variables(set = Set.new)
|
39
|
+
type.free_variables(set)
|
40
|
+
mask.free_variables(set)
|
41
|
+
end
|
42
|
+
|
43
|
+
def each_type(&block)
|
44
|
+
if block_given?
|
45
|
+
yield type
|
46
|
+
yield mask
|
47
|
+
else
|
48
|
+
enum_for :each_type
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def sub(s)
|
53
|
+
self.class.new(type: type.sub(s),
|
54
|
+
mask: mask.sub(s),
|
55
|
+
location: location)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/steep/ast/types/any.rb
CHANGED
@@ -0,0 +1,535 @@
|
|
1
|
+
module Steep
|
2
|
+
module AST
|
3
|
+
module Types
|
4
|
+
class Factory
|
5
|
+
attr_reader :definition_builder
|
6
|
+
|
7
|
+
def initialize(builder:)
|
8
|
+
@definition_builder = builder
|
9
|
+
end
|
10
|
+
|
11
|
+
def type(type)
|
12
|
+
case type
|
13
|
+
when Ruby::Signature::Types::Bases::Any
|
14
|
+
Any.new(location: nil)
|
15
|
+
when Ruby::Signature::Types::Bases::Class
|
16
|
+
Class.new(location: nil)
|
17
|
+
when Ruby::Signature::Types::Bases::Instance
|
18
|
+
Instance.new(location: nil)
|
19
|
+
when Ruby::Signature::Types::Bases::Self
|
20
|
+
Self.new(location: nil)
|
21
|
+
when Ruby::Signature::Types::Bases::Top
|
22
|
+
Top.new(location: nil)
|
23
|
+
when Ruby::Signature::Types::Bases::Bottom
|
24
|
+
Bot.new(location: nil)
|
25
|
+
when Ruby::Signature::Types::Bases::Bool
|
26
|
+
Boolean.new(location: nil)
|
27
|
+
when Ruby::Signature::Types::Bases::Void
|
28
|
+
Void.new(location: nil)
|
29
|
+
when Ruby::Signature::Types::Bases::Nil
|
30
|
+
Nil.new(location: nil)
|
31
|
+
when Ruby::Signature::Types::Variable
|
32
|
+
Var.new(name: type.name, location: nil)
|
33
|
+
when Ruby::Signature::Types::ClassSingleton
|
34
|
+
type_name = type_name(type.name)
|
35
|
+
Name::Class.new(name: type_name, location: nil, constructor: nil)
|
36
|
+
when Ruby::Signature::Types::ClassInstance
|
37
|
+
type_name = type_name(type.name)
|
38
|
+
args = type.args.map {|arg| type(arg) }
|
39
|
+
Name::Instance.new(name: type_name, args: args, location: nil)
|
40
|
+
when Ruby::Signature::Types::Interface
|
41
|
+
type_name = type_name(type.name)
|
42
|
+
args = type.args.map {|arg| type(arg) }
|
43
|
+
Name::Interface.new(name: type_name, args: args, location: nil)
|
44
|
+
when Ruby::Signature::Types::Alias
|
45
|
+
type_name = type_name(type.name)
|
46
|
+
Name::Alias.new(name: type_name, args: [], location: nil)
|
47
|
+
when Ruby::Signature::Types::Union
|
48
|
+
Union.build(types: type.types.map {|ty| type(ty) }, location: nil)
|
49
|
+
when Ruby::Signature::Types::Intersection
|
50
|
+
Intersection.build(types: type.types.map {|ty| type(ty) }, location: nil)
|
51
|
+
when Ruby::Signature::Types::Optional
|
52
|
+
Union.build(types: [type(type.type), Nil.new(location: nil)], location: nil)
|
53
|
+
when Ruby::Signature::Types::Literal
|
54
|
+
Literal.new(value: type.literal, location: nil)
|
55
|
+
when Ruby::Signature::Types::Tuple
|
56
|
+
Tuple.new(types: type.types.map {|ty| type(ty) }, location: nil)
|
57
|
+
when Ruby::Signature::Types::Record
|
58
|
+
elements = type.fields.each.with_object({}) do |(key, value), hash|
|
59
|
+
hash[key] = type(value)
|
60
|
+
end
|
61
|
+
Record.new(elements: elements, location: nil)
|
62
|
+
when Ruby::Signature::Types::Proc
|
63
|
+
params = params(type.type)
|
64
|
+
return_type = type(type.type.return_type)
|
65
|
+
Proc.new(params: params, return_type: return_type, location: nil)
|
66
|
+
else
|
67
|
+
raise "Unexpected type given: #{type}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def type_1(type)
|
72
|
+
case type
|
73
|
+
when Any
|
74
|
+
Ruby::Signature::Types::Bases::Any.new(location: nil)
|
75
|
+
when Class
|
76
|
+
Ruby::Signature::Types::Bases::Class.new(location: nil)
|
77
|
+
when Instance
|
78
|
+
Ruby::Signature::Types::Bases::Instance.new(location: nil)
|
79
|
+
when Self
|
80
|
+
Ruby::Signature::Types::Bases::Self.new(location: nil)
|
81
|
+
when Top
|
82
|
+
Ruby::Signature::Types::Bases::Top.new(location: nil)
|
83
|
+
when Bot
|
84
|
+
Ruby::Signature::Types::Bases::Bottom.new(location: nil)
|
85
|
+
when Boolean
|
86
|
+
Ruby::Signature::Types::Bases::Bool.new(location: nil)
|
87
|
+
when Void
|
88
|
+
Ruby::Signature::Types::Bases::Void.new(location: nil)
|
89
|
+
when Nil
|
90
|
+
Ruby::Signature::Types::Bases::Nil.new(location: nil)
|
91
|
+
when Var
|
92
|
+
Ruby::Signature::Types::Variable.new(name: type.name, location: nil)
|
93
|
+
when Name::Class, Name::Module
|
94
|
+
Ruby::Signature::Types::ClassSingleton.new(name: type_name_1(type.name), location: nil)
|
95
|
+
when Name::Instance
|
96
|
+
Ruby::Signature::Types::ClassInstance.new(
|
97
|
+
name: type_name_1(type.name),
|
98
|
+
args: type.args.map {|arg| type_1(arg) },
|
99
|
+
location: nil
|
100
|
+
)
|
101
|
+
when Name::Interface
|
102
|
+
Ruby::Signature::Types::Interface.new(
|
103
|
+
name: type_name_1(type.name),
|
104
|
+
args: type.args.map {|arg| type_1(arg) },
|
105
|
+
location: nil
|
106
|
+
)
|
107
|
+
when Name::Alias
|
108
|
+
type.args.empty? or raise "alias type with args is not supported"
|
109
|
+
Ruby::Signature::Types::Alias.new(name: type_name_1(type.name), location: nil)
|
110
|
+
when Union
|
111
|
+
Ruby::Signature::Types::Union.new(
|
112
|
+
types: type.types.map {|ty| type_1(ty) },
|
113
|
+
location: nil
|
114
|
+
)
|
115
|
+
when Intersection
|
116
|
+
Ruby::Signature::Types::Intersection.new(
|
117
|
+
types: type.types.map {|ty| type_1(ty) },
|
118
|
+
location: nil
|
119
|
+
)
|
120
|
+
when Literal
|
121
|
+
Ruby::Signature::Types::Literal.new(literal: type.value, location: nil)
|
122
|
+
when Tuple
|
123
|
+
Ruby::Signature::Types::Tuple.new(
|
124
|
+
types: type.types.map {|ty| type_1(ty) },
|
125
|
+
location: nil
|
126
|
+
)
|
127
|
+
when Record
|
128
|
+
fields = type.elements.each.with_object({}) do |(key, value), hash|
|
129
|
+
hash[key] = type_1(value)
|
130
|
+
end
|
131
|
+
Ruby::Signature::Types::Record.new(fields: fields, location: nil)
|
132
|
+
when Proc
|
133
|
+
Ruby::Signature::Types::Proc.new(
|
134
|
+
type: function_1(type.params, type.return_type),
|
135
|
+
location: nil
|
136
|
+
)
|
137
|
+
else
|
138
|
+
raise "Unexpected type given: #{type} (#{type.class})"
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def type_name(name)
|
143
|
+
case
|
144
|
+
when name.class?
|
145
|
+
Names::Module.new(name: name.name, namespace: namespace(name.namespace), location: nil)
|
146
|
+
when name.interface?
|
147
|
+
Names::Interface.new(name: name.name, namespace: namespace(name.namespace), location: nil)
|
148
|
+
when name.alias?
|
149
|
+
Names::Alias.new(name: name.name, namespace: namespace(name.namespace), location: nil)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def type_name_1(name)
|
154
|
+
Ruby::Signature::TypeName.new(name: name.name, namespace: namespace_1(name.namespace))
|
155
|
+
end
|
156
|
+
|
157
|
+
def namespace(namespace)
|
158
|
+
Namespace.parse(namespace.to_s)
|
159
|
+
end
|
160
|
+
|
161
|
+
def namespace_1(namespace)
|
162
|
+
Ruby::Signature::Namespace.parse(namespace.to_s)
|
163
|
+
end
|
164
|
+
|
165
|
+
def function_1(params, return_type)
|
166
|
+
Ruby::Signature::Types::Function.new(
|
167
|
+
required_positionals: params.required.map {|type| Ruby::Signature::Types::Function::Param.new(name: nil, type: type_1(type)) },
|
168
|
+
optional_positionals: params.optional.map {|type| Ruby::Signature::Types::Function::Param.new(name: nil, type: type_1(type)) },
|
169
|
+
rest_positionals: params.rest&.yield_self {|type| Ruby::Signature::Types::Function::Param.new(name: nil, type: type_1(type)) },
|
170
|
+
trailing_positionals: [],
|
171
|
+
required_keywords: params.required_keywords.transform_values {|type| Ruby::Signature::Types::Function::Param.new(name: nil, type: type_1(type)) },
|
172
|
+
optional_keywords: params.optional_keywords.transform_values {|type| Ruby::Signature::Types::Function::Param.new(name: nil, type: type_1(type)) },
|
173
|
+
rest_keywords: params.rest_keywords&.yield_self {|type| Ruby::Signature::Types::Function::Param.new(name: nil, type: type_1(type)) },
|
174
|
+
return_type: type_1(return_type)
|
175
|
+
)
|
176
|
+
end
|
177
|
+
|
178
|
+
def params(type)
|
179
|
+
Interface::Params.new(
|
180
|
+
required: type.required_positionals.map {|param| type(param.type) },
|
181
|
+
optional: type.optional_positionals.map {|param| type(param.type) },
|
182
|
+
rest: type.rest_positionals&.yield_self {|param| type(param.type) },
|
183
|
+
required_keywords: type.required_keywords.transform_values {|param| type(param.type) },
|
184
|
+
optional_keywords: type.optional_keywords.transform_values {|param| type(param.type) },
|
185
|
+
rest_keywords: type.rest_keywords&.yield_self {|param| type(param.type) }
|
186
|
+
)
|
187
|
+
end
|
188
|
+
|
189
|
+
def method_type(method_type, self_type:)
|
190
|
+
case method_type
|
191
|
+
when Ruby::Signature::MethodType
|
192
|
+
fvs = self_type.free_variables()
|
193
|
+
|
194
|
+
type_params = []
|
195
|
+
alpha_vars = []
|
196
|
+
alpha_types = []
|
197
|
+
|
198
|
+
method_type.type_params.map do |name|
|
199
|
+
if fvs.include?(name)
|
200
|
+
type = Types::Var.fresh(name)
|
201
|
+
alpha_vars << name
|
202
|
+
alpha_types << type
|
203
|
+
type_params << type.name
|
204
|
+
else
|
205
|
+
type_params << name
|
206
|
+
end
|
207
|
+
end
|
208
|
+
subst = Interface::Substitution.build(alpha_vars, alpha_types)
|
209
|
+
|
210
|
+
type = Interface::MethodType.new(
|
211
|
+
type_params: type_params,
|
212
|
+
return_type: type(method_type.type.return_type).subst(subst),
|
213
|
+
params: params(method_type.type).subst(subst),
|
214
|
+
location: nil,
|
215
|
+
block: method_type.block&.yield_self do |block|
|
216
|
+
Interface::Block.new(
|
217
|
+
optional: !block.required,
|
218
|
+
type: Proc.new(params: params(block.type).subst(subst),
|
219
|
+
return_type: type(block.type.return_type).subst(subst), location: nil)
|
220
|
+
)
|
221
|
+
end
|
222
|
+
)
|
223
|
+
|
224
|
+
if block_given?
|
225
|
+
yield type
|
226
|
+
else
|
227
|
+
type
|
228
|
+
end
|
229
|
+
when :any
|
230
|
+
:any
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
class InterfaceCalculationError < StandardError
|
235
|
+
attr_reader :type
|
236
|
+
|
237
|
+
def initialize(type:, message:)
|
238
|
+
@type = type
|
239
|
+
super message
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
def unfold(type_name)
|
244
|
+
type_name_1(type_name).yield_self do |type_name|
|
245
|
+
decl = definition_builder.env.find_alias(type_name) or raise "Unknown type name: #{type_name}"
|
246
|
+
type(definition_builder.env.absolute_type(decl.type, namespace: type_name.namespace))
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
def expand_alias(type)
|
251
|
+
unfolded = case type
|
252
|
+
when AST::Types::Name::Alias
|
253
|
+
unfolded = unfold(type.name)
|
254
|
+
else
|
255
|
+
type
|
256
|
+
end
|
257
|
+
|
258
|
+
if block_given?
|
259
|
+
yield unfolded
|
260
|
+
else
|
261
|
+
unfolded
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
def interface(type, private:, self_type: type)
|
266
|
+
type = expand_alias(type)
|
267
|
+
|
268
|
+
case type
|
269
|
+
when Self
|
270
|
+
if self_type != type
|
271
|
+
interface self_type, private: private, self_type: Self.new
|
272
|
+
else
|
273
|
+
raise "Unexpected `self` type interface"
|
274
|
+
end
|
275
|
+
when Name::Instance
|
276
|
+
Interface::Interface.new(type: self_type, private: private).tap do |interface|
|
277
|
+
definition = definition_builder.build_instance(type_name_1(type.name))
|
278
|
+
|
279
|
+
instance_type = Name::Instance.new(name: type.name,
|
280
|
+
args: type.args.map { Any.new(location: nil) },
|
281
|
+
location: nil)
|
282
|
+
module_type = type.to_module()
|
283
|
+
|
284
|
+
subst = Interface::Substitution.build(
|
285
|
+
definition.type_params,
|
286
|
+
type.args,
|
287
|
+
instance_type: instance_type,
|
288
|
+
module_type: module_type,
|
289
|
+
self_type: self_type
|
290
|
+
)
|
291
|
+
|
292
|
+
definition.methods.each do |name, method|
|
293
|
+
next if method.private? && !private
|
294
|
+
|
295
|
+
interface.methods[name] = Interface::Interface::Combination.overload(
|
296
|
+
method.method_types.map do |type|
|
297
|
+
method_type(type, self_type: self_type) {|ty| ty.subst(subst) }
|
298
|
+
end,
|
299
|
+
incompatible: method.attributes.include?(:incompatible)
|
300
|
+
)
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
when Name::Interface
|
305
|
+
Interface::Interface.new(type: self_type, private: private).tap do |interface|
|
306
|
+
type_name = type_name_1(type.name)
|
307
|
+
decl = definition_builder.env.find_class(type_name) or raise "Unknown class: #{type_name}"
|
308
|
+
definition = definition_builder.build_interface(type_name, decl)
|
309
|
+
|
310
|
+
subst = Interface::Substitution.build(
|
311
|
+
definition.type_params,
|
312
|
+
type.args,
|
313
|
+
self_type: self_type
|
314
|
+
)
|
315
|
+
|
316
|
+
definition.methods.each do |name, method|
|
317
|
+
interface.methods[name] = Interface::Interface::Combination.overload(
|
318
|
+
method.method_types.map do |type|
|
319
|
+
method_type(type, self_type: self_type) {|type| type.subst(subst) }
|
320
|
+
end,
|
321
|
+
incompatible: method.attributes.include?(:incompatible)
|
322
|
+
)
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
when Name::Class, Name::Module
|
327
|
+
Interface::Interface.new(type: self_type, private: private).tap do |interface|
|
328
|
+
definition = definition_builder.build_singleton(type_name_1(type.name))
|
329
|
+
|
330
|
+
instance_type = Name::Instance.new(name: type.name,
|
331
|
+
args: definition.declaration.type_params.each.map {Any.new(location: nil)},
|
332
|
+
location: nil)
|
333
|
+
subst = Interface::Substitution.build(
|
334
|
+
[],
|
335
|
+
instance_type: instance_type,
|
336
|
+
module_type: type,
|
337
|
+
self_type: self_type
|
338
|
+
)
|
339
|
+
|
340
|
+
definition.methods.each do |name, method|
|
341
|
+
next if !private && method.private?
|
342
|
+
|
343
|
+
interface.methods[name] = Interface::Interface::Combination.overload(
|
344
|
+
method.method_types.map do |type|
|
345
|
+
method_type(type, self_type: self_type) {|type| type.subst(subst) }
|
346
|
+
end,
|
347
|
+
incompatible: method.attributes.include?(:incompatible)
|
348
|
+
)
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
when Literal
|
353
|
+
interface type.back_type, private: private, self_type: self_type
|
354
|
+
|
355
|
+
when Nil
|
356
|
+
interface Builtin::NilClass.instance_type, private: private, self_type: self_type
|
357
|
+
|
358
|
+
when Boolean
|
359
|
+
interface(AST::Types::Union.build(types: [Builtin::TrueClass.instance_type, Builtin::FalseClass.instance_type]),
|
360
|
+
private: private,
|
361
|
+
self_type: self_type)
|
362
|
+
|
363
|
+
when Union
|
364
|
+
yield_self do
|
365
|
+
interfaces = type.types.map {|ty| interface(ty, private: private, self_type: self_type) }
|
366
|
+
interfaces.inject do |interface1, interface2|
|
367
|
+
Interface::Interface.new(type: self_type, private: private).tap do |interface|
|
368
|
+
common_methods = Set.new(interface1.methods.keys) & Set.new(interface2.methods.keys)
|
369
|
+
common_methods.each do |name|
|
370
|
+
interface.methods[name] = Interface::Interface::Combination.union([interface1.methods[name], interface2.methods[name]])
|
371
|
+
end
|
372
|
+
end
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
when Intersection
|
377
|
+
yield_self do
|
378
|
+
interfaces = type.types.map {|ty| interface(ty, private: private, self_type: self_type) }
|
379
|
+
interfaces.inject do |interface1, interface2|
|
380
|
+
Interface::Interface.new(type: self_type, private: private).tap do |interface|
|
381
|
+
all_methods = Set.new(interface1.methods.keys) + Set.new(interface2.methods.keys)
|
382
|
+
all_methods.each do |name|
|
383
|
+
methods = [interface1.methods[name], interface2.methods[name]].compact
|
384
|
+
interface.methods[name] = Interface::Interface::Combination.intersection(methods)
|
385
|
+
end
|
386
|
+
end
|
387
|
+
end
|
388
|
+
end
|
389
|
+
|
390
|
+
when Tuple
|
391
|
+
yield_self do
|
392
|
+
element_type = Union.build(types: type.types, location: nil)
|
393
|
+
array_type = Builtin::Array.instance_type(element_type)
|
394
|
+
interface(array_type, private: private, self_type: self_type).tap do |array_interface|
|
395
|
+
array_interface.methods[:[]] = array_interface.methods[:[]].yield_self do |aref|
|
396
|
+
Interface::Interface::Combination.overload(
|
397
|
+
type.types.map.with_index {|elem_type, index|
|
398
|
+
Interface::MethodType.new(
|
399
|
+
type_params: [],
|
400
|
+
params: Interface::Params.new(required: [AST::Types::Literal.new(value: index)],
|
401
|
+
optional: [],
|
402
|
+
rest: nil,
|
403
|
+
required_keywords: {},
|
404
|
+
optional_keywords: {},
|
405
|
+
rest_keywords: nil),
|
406
|
+
block: nil,
|
407
|
+
return_type: elem_type,
|
408
|
+
location: nil
|
409
|
+
)
|
410
|
+
} + aref.types,
|
411
|
+
incompatible: false
|
412
|
+
)
|
413
|
+
end
|
414
|
+
|
415
|
+
array_interface.methods[:[]=] = array_interface.methods[:[]=].yield_self do |update|
|
416
|
+
Interface::Interface::Combination.overload(
|
417
|
+
type.types.map.with_index {|elem_type, index|
|
418
|
+
Interface::MethodType.new(
|
419
|
+
type_params: [],
|
420
|
+
params: Interface::Params.new(required: [AST::Types::Literal.new(value: index), elem_type],
|
421
|
+
optional: [],
|
422
|
+
rest: nil,
|
423
|
+
required_keywords: {},
|
424
|
+
optional_keywords: {},
|
425
|
+
rest_keywords: nil),
|
426
|
+
block: nil,
|
427
|
+
return_type: elem_type,
|
428
|
+
location: nil
|
429
|
+
)
|
430
|
+
} + update.types,
|
431
|
+
incompatible: false
|
432
|
+
)
|
433
|
+
end
|
434
|
+
end
|
435
|
+
end
|
436
|
+
|
437
|
+
when Record
|
438
|
+
yield_self do
|
439
|
+
key_type = type.elements.keys.map {|value| Literal.new(value: value, location: nil) }.yield_self do |types|
|
440
|
+
Union.build(types: types, location: nil)
|
441
|
+
end
|
442
|
+
value_type = Union.build(types: type.elements.values, location: nil)
|
443
|
+
hash_type = Builtin::Hash.instance_type(key_type, value_type)
|
444
|
+
|
445
|
+
interface(hash_type, private: private, self_type: self_type).tap do |hash_interface|
|
446
|
+
hash_interface.methods[:[]] = hash_interface.methods[:[]].yield_self do |ref|
|
447
|
+
Interface::Interface::Combination.overload(
|
448
|
+
type.elements.map {|key_value, value_type|
|
449
|
+
key_type = Literal.new(value: key_value, location: nil)
|
450
|
+
Interface::MethodType.new(
|
451
|
+
type_params: [],
|
452
|
+
params: Interface::Params.new(required: [key_type],
|
453
|
+
optional: [],
|
454
|
+
rest: nil,
|
455
|
+
required_keywords: {},
|
456
|
+
optional_keywords: {},
|
457
|
+
rest_keywords: nil),
|
458
|
+
block: nil,
|
459
|
+
return_type: value_type,
|
460
|
+
location: nil
|
461
|
+
)
|
462
|
+
} + ref.types,
|
463
|
+
incompatible: false
|
464
|
+
)
|
465
|
+
end
|
466
|
+
|
467
|
+
hash_interface.methods[:[]=] = hash_interface.methods[:[]=].yield_self do |update|
|
468
|
+
Interface::Interface::Combination.overload(
|
469
|
+
type.elements.map {|key_value, value_type|
|
470
|
+
key_type = Literal.new(value: key_value, location: nil)
|
471
|
+
Interface::MethodType.new(
|
472
|
+
type_params: [],
|
473
|
+
params: Interface::Params.new(required: [key_type, value_type],
|
474
|
+
optional: [],
|
475
|
+
rest: nil,
|
476
|
+
required_keywords: {},
|
477
|
+
optional_keywords: {},
|
478
|
+
rest_keywords: nil),
|
479
|
+
block: nil,
|
480
|
+
return_type: value_type,
|
481
|
+
location: nil
|
482
|
+
)
|
483
|
+
} + update.types,
|
484
|
+
incompatible: false
|
485
|
+
)
|
486
|
+
end
|
487
|
+
end
|
488
|
+
end
|
489
|
+
|
490
|
+
when Proc
|
491
|
+
interface(Builtin::Proc.instance_type, private: private, self_type: self_type).tap do |interface|
|
492
|
+
method_type = Interface::MethodType.new(
|
493
|
+
type_params: [],
|
494
|
+
params: type.params,
|
495
|
+
return_type: type.return_type,
|
496
|
+
block: nil,
|
497
|
+
location: nil
|
498
|
+
)
|
499
|
+
|
500
|
+
interface.methods[:[]] = Interface::Interface::Combination.overload([method_type], incompatible: false)
|
501
|
+
interface.methods[:call] = Interface::Interface::Combination.overload([method_type], incompatible: false)
|
502
|
+
end
|
503
|
+
|
504
|
+
else
|
505
|
+
raise "Unexpected type for interface: #{type}"
|
506
|
+
end
|
507
|
+
end
|
508
|
+
|
509
|
+
def module_name?(type_name)
|
510
|
+
name = type_name_1(type_name)
|
511
|
+
env.class?(name) && env.find_class(name).is_a?(Ruby::Signature::AST::Declarations::Module)
|
512
|
+
end
|
513
|
+
|
514
|
+
def class_name?(type_name)
|
515
|
+
name = type_name_1(type_name)
|
516
|
+
env.class?(name) && env.find_class(name).is_a?(Ruby::Signature::AST::Declarations::Class)
|
517
|
+
end
|
518
|
+
|
519
|
+
def env
|
520
|
+
@env ||= definition_builder.env
|
521
|
+
end
|
522
|
+
|
523
|
+
def absolute_type(type, namespace:)
|
524
|
+
type(env.absolute_type(type_1(type),
|
525
|
+
namespace: namespace_1(namespace)) {|type| type.name.absolute! })
|
526
|
+
end
|
527
|
+
|
528
|
+
def absolute_type_name(type_name, namespace:)
|
529
|
+
type(env.absolute_type_name(type_name_1(type_name),
|
530
|
+
namespace: namespace_1(namespace)) {|name| name.absolute! })
|
531
|
+
end
|
532
|
+
end
|
533
|
+
end
|
534
|
+
end
|
535
|
+
end
|