steep-relaxed 1.9.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.gitmodules +0 -0
- data/CHANGELOG.md +1032 -0
- data/LICENSE +21 -0
- data/README.md +260 -0
- data/Rakefile +227 -0
- data/STDGEM_DEPENDENCIES.txt +59 -0
- data/Steepfile +68 -0
- data/bin/console +14 -0
- data/bin/generate-diagnostics-docs.rb +112 -0
- data/bin/mem_graph.rb +67 -0
- data/bin/mem_prof.rb +102 -0
- data/bin/output_rebaseline.rb +34 -0
- data/bin/output_test.rb +60 -0
- data/bin/rbs +20 -0
- data/bin/rbs-inline +19 -0
- data/bin/setup +9 -0
- data/bin/stackprof_test.rb +19 -0
- data/bin/steep +19 -0
- data/bin/steep-check.rb +251 -0
- data/bin/steep-prof +16 -0
- data/doc/narrowing.md +195 -0
- data/doc/shape.md +194 -0
- data/exe/steep +18 -0
- data/guides/README.md +5 -0
- data/guides/src/gem-rbs-collection/gem-rbs-collection.md +126 -0
- data/guides/src/getting-started/getting-started.md +163 -0
- data/guides/src/nil-optional/nil-optional.md +195 -0
- data/lib/steep/annotation_parser.rb +199 -0
- data/lib/steep/ast/annotation/collection.rb +172 -0
- data/lib/steep/ast/annotation.rb +137 -0
- data/lib/steep/ast/builtin.rb +104 -0
- data/lib/steep/ast/ignore.rb +148 -0
- data/lib/steep/ast/node/type_application.rb +88 -0
- data/lib/steep/ast/node/type_assertion.rb +81 -0
- data/lib/steep/ast/types/any.rb +35 -0
- data/lib/steep/ast/types/boolean.rb +45 -0
- data/lib/steep/ast/types/bot.rb +35 -0
- data/lib/steep/ast/types/class.rb +43 -0
- data/lib/steep/ast/types/factory.rb +557 -0
- data/lib/steep/ast/types/helper.rb +40 -0
- data/lib/steep/ast/types/instance.rb +42 -0
- data/lib/steep/ast/types/intersection.rb +93 -0
- data/lib/steep/ast/types/literal.rb +59 -0
- data/lib/steep/ast/types/logic.rb +84 -0
- data/lib/steep/ast/types/name.rb +128 -0
- data/lib/steep/ast/types/nil.rb +41 -0
- data/lib/steep/ast/types/proc.rb +117 -0
- data/lib/steep/ast/types/record.rb +79 -0
- data/lib/steep/ast/types/self.rb +43 -0
- data/lib/steep/ast/types/shared_instance.rb +11 -0
- data/lib/steep/ast/types/top.rb +35 -0
- data/lib/steep/ast/types/tuple.rb +60 -0
- data/lib/steep/ast/types/union.rb +97 -0
- data/lib/steep/ast/types/var.rb +65 -0
- data/lib/steep/ast/types/void.rb +35 -0
- data/lib/steep/cli.rb +401 -0
- data/lib/steep/diagnostic/deprecated/else_on_exhaustive_case.rb +20 -0
- data/lib/steep/diagnostic/deprecated/unknown_constant_assigned.rb +28 -0
- data/lib/steep/diagnostic/helper.rb +18 -0
- data/lib/steep/diagnostic/lsp_formatter.rb +78 -0
- data/lib/steep/diagnostic/result_printer2.rb +48 -0
- data/lib/steep/diagnostic/ruby.rb +1221 -0
- data/lib/steep/diagnostic/signature.rb +570 -0
- data/lib/steep/drivers/annotations.rb +52 -0
- data/lib/steep/drivers/check.rb +339 -0
- data/lib/steep/drivers/checkfile.rb +210 -0
- data/lib/steep/drivers/diagnostic_printer.rb +105 -0
- data/lib/steep/drivers/init.rb +66 -0
- data/lib/steep/drivers/langserver.rb +56 -0
- data/lib/steep/drivers/print_project.rb +113 -0
- data/lib/steep/drivers/stats.rb +203 -0
- data/lib/steep/drivers/utils/driver_helper.rb +143 -0
- data/lib/steep/drivers/utils/jobs_option.rb +26 -0
- data/lib/steep/drivers/vendor.rb +27 -0
- data/lib/steep/drivers/watch.rb +194 -0
- data/lib/steep/drivers/worker.rb +58 -0
- data/lib/steep/equatable.rb +23 -0
- data/lib/steep/expectations.rb +228 -0
- data/lib/steep/index/rbs_index.rb +350 -0
- data/lib/steep/index/signature_symbol_provider.rb +185 -0
- data/lib/steep/index/source_index.rb +167 -0
- data/lib/steep/interface/block.rb +103 -0
- data/lib/steep/interface/builder.rb +843 -0
- data/lib/steep/interface/function.rb +1090 -0
- data/lib/steep/interface/method_type.rb +330 -0
- data/lib/steep/interface/shape.rb +239 -0
- data/lib/steep/interface/substitution.rb +159 -0
- data/lib/steep/interface/type_param.rb +115 -0
- data/lib/steep/located_value.rb +20 -0
- data/lib/steep/method_name.rb +42 -0
- data/lib/steep/module_helper.rb +24 -0
- data/lib/steep/node_helper.rb +273 -0
- data/lib/steep/path_helper.rb +30 -0
- data/lib/steep/project/dsl.rb +268 -0
- data/lib/steep/project/group.rb +31 -0
- data/lib/steep/project/options.rb +63 -0
- data/lib/steep/project/pattern.rb +59 -0
- data/lib/steep/project/target.rb +92 -0
- data/lib/steep/project.rb +78 -0
- data/lib/steep/rake_task.rb +132 -0
- data/lib/steep/range_extension.rb +29 -0
- data/lib/steep/server/base_worker.rb +97 -0
- data/lib/steep/server/change_buffer.rb +73 -0
- data/lib/steep/server/custom_methods.rb +77 -0
- data/lib/steep/server/delay_queue.rb +45 -0
- data/lib/steep/server/interaction_worker.rb +492 -0
- data/lib/steep/server/lsp_formatter.rb +455 -0
- data/lib/steep/server/master.rb +922 -0
- data/lib/steep/server/target_group_files.rb +205 -0
- data/lib/steep/server/type_check_controller.rb +366 -0
- data/lib/steep/server/type_check_worker.rb +303 -0
- data/lib/steep/server/work_done_progress.rb +64 -0
- data/lib/steep/server/worker_process.rb +176 -0
- data/lib/steep/services/completion_provider.rb +802 -0
- data/lib/steep/services/content_change.rb +61 -0
- data/lib/steep/services/file_loader.rb +74 -0
- data/lib/steep/services/goto_service.rb +441 -0
- data/lib/steep/services/hover_provider/rbs.rb +88 -0
- data/lib/steep/services/hover_provider/ruby.rb +221 -0
- data/lib/steep/services/hover_provider/singleton_methods.rb +20 -0
- data/lib/steep/services/path_assignment.rb +46 -0
- data/lib/steep/services/signature_help_provider.rb +202 -0
- data/lib/steep/services/signature_service.rb +428 -0
- data/lib/steep/services/stats_calculator.rb +68 -0
- data/lib/steep/services/type_check_service.rb +394 -0
- data/lib/steep/services/type_name_completion.rb +236 -0
- data/lib/steep/signature/validator.rb +651 -0
- data/lib/steep/source/ignore_ranges.rb +69 -0
- data/lib/steep/source.rb +691 -0
- data/lib/steep/subtyping/cache.rb +30 -0
- data/lib/steep/subtyping/check.rb +1113 -0
- data/lib/steep/subtyping/constraints.rb +341 -0
- data/lib/steep/subtyping/relation.rb +101 -0
- data/lib/steep/subtyping/result.rb +324 -0
- data/lib/steep/subtyping/variable_variance.rb +89 -0
- data/lib/steep/test.rb +9 -0
- data/lib/steep/thread_waiter.rb +43 -0
- data/lib/steep/type_construction.rb +5183 -0
- data/lib/steep/type_inference/block_params.rb +416 -0
- data/lib/steep/type_inference/case_when.rb +303 -0
- data/lib/steep/type_inference/constant_env.rb +56 -0
- data/lib/steep/type_inference/context.rb +195 -0
- data/lib/steep/type_inference/logic_type_interpreter.rb +613 -0
- data/lib/steep/type_inference/method_call.rb +193 -0
- data/lib/steep/type_inference/method_params.rb +531 -0
- data/lib/steep/type_inference/multiple_assignment.rb +194 -0
- data/lib/steep/type_inference/send_args.rb +712 -0
- data/lib/steep/type_inference/type_env.rb +341 -0
- data/lib/steep/type_inference/type_env_builder.rb +138 -0
- data/lib/steep/typing.rb +321 -0
- data/lib/steep/version.rb +3 -0
- data/lib/steep.rb +369 -0
- data/manual/annotations.md +181 -0
- data/manual/ignore.md +20 -0
- data/manual/ruby-diagnostics.md +1879 -0
- data/sample/Steepfile +22 -0
- data/sample/lib/conference.rb +49 -0
- data/sample/lib/length.rb +35 -0
- data/sample/sig/conference.rbs +42 -0
- data/sample/sig/generics.rbs +15 -0
- data/sample/sig/length.rbs +34 -0
- data/steep-relaxed.gemspec +56 -0
- metadata +340 -0
@@ -0,0 +1,93 @@
|
|
1
|
+
module Steep
|
2
|
+
module AST
|
3
|
+
module Types
|
4
|
+
class Intersection
|
5
|
+
attr_reader :types
|
6
|
+
|
7
|
+
def initialize(types:)
|
8
|
+
@types = types
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.build(types:)
|
12
|
+
types.flat_map do |type|
|
13
|
+
if type.is_a?(Intersection)
|
14
|
+
type.types
|
15
|
+
else
|
16
|
+
[type]
|
17
|
+
end
|
18
|
+
end.map do |type|
|
19
|
+
case type
|
20
|
+
when AST::Types::Any
|
21
|
+
return AST::Types::Any.instance()
|
22
|
+
when AST::Types::Bot
|
23
|
+
return AST::Types::Bot.instance
|
24
|
+
when AST::Types::Top
|
25
|
+
nil
|
26
|
+
else
|
27
|
+
type
|
28
|
+
end
|
29
|
+
end.compact.yield_self do |tys|
|
30
|
+
dups = Set.new(tys)
|
31
|
+
|
32
|
+
case dups.size
|
33
|
+
when 0
|
34
|
+
AST::Types::Top.instance
|
35
|
+
when 1
|
36
|
+
tys.first || raise
|
37
|
+
else
|
38
|
+
new(types: dups.to_a)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def ==(other)
|
44
|
+
other.is_a?(Intersection) && other.types == types
|
45
|
+
end
|
46
|
+
|
47
|
+
def hash
|
48
|
+
@hash ||= self.class.hash ^ types.hash
|
49
|
+
end
|
50
|
+
|
51
|
+
alias eql? ==
|
52
|
+
|
53
|
+
def subst(s)
|
54
|
+
self.class.build(types: types.map {|ty| ty.subst(s) })
|
55
|
+
end
|
56
|
+
|
57
|
+
def to_s
|
58
|
+
"(#{types.map(&:to_s).join(" & ")})"
|
59
|
+
end
|
60
|
+
|
61
|
+
def free_variables()
|
62
|
+
@fvs ||= begin
|
63
|
+
set = Set.new
|
64
|
+
types.each do |type|
|
65
|
+
set.merge(type.free_variables)
|
66
|
+
end
|
67
|
+
set
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
include Helper::ChildrenLevel
|
72
|
+
|
73
|
+
def each_child(&block)
|
74
|
+
if block
|
75
|
+
types.each(&block)
|
76
|
+
else
|
77
|
+
types.each
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def map_type(&block)
|
82
|
+
self.class.build(
|
83
|
+
types: each_child.map(&block)
|
84
|
+
)
|
85
|
+
end
|
86
|
+
|
87
|
+
def level
|
88
|
+
[0] + level_of_children(types)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Steep
|
2
|
+
module AST
|
3
|
+
module Types
|
4
|
+
class Literal
|
5
|
+
attr_reader :value
|
6
|
+
|
7
|
+
def initialize(value:)
|
8
|
+
@value = value
|
9
|
+
end
|
10
|
+
|
11
|
+
def ==(other)
|
12
|
+
other.is_a?(Literal) &&
|
13
|
+
other.value == value
|
14
|
+
end
|
15
|
+
|
16
|
+
def hash
|
17
|
+
self.class.hash
|
18
|
+
end
|
19
|
+
|
20
|
+
alias eql? ==
|
21
|
+
|
22
|
+
def subst(s)
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_s
|
27
|
+
value.inspect
|
28
|
+
end
|
29
|
+
|
30
|
+
include Helper::NoFreeVariables
|
31
|
+
|
32
|
+
include Helper::NoChild
|
33
|
+
|
34
|
+
def level
|
35
|
+
[0]
|
36
|
+
end
|
37
|
+
|
38
|
+
def back_type
|
39
|
+
klass = case value
|
40
|
+
when Integer
|
41
|
+
Builtin::Integer
|
42
|
+
when String
|
43
|
+
Builtin::String
|
44
|
+
when Symbol
|
45
|
+
Builtin::Symbol
|
46
|
+
when true
|
47
|
+
Builtin::TrueClass
|
48
|
+
when false
|
49
|
+
Builtin::FalseClass
|
50
|
+
else
|
51
|
+
raise "Unexpected literal type: #{(_ = value).inspect}"
|
52
|
+
end
|
53
|
+
|
54
|
+
Name::Instance.new(name: klass.module_name, args: [])
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module Steep
|
2
|
+
module AST
|
3
|
+
module Types
|
4
|
+
module Logic
|
5
|
+
class Base
|
6
|
+
extend SharedInstance
|
7
|
+
|
8
|
+
def subst(s)
|
9
|
+
self
|
10
|
+
end
|
11
|
+
|
12
|
+
include Helper::NoFreeVariables
|
13
|
+
|
14
|
+
include Helper::NoChild
|
15
|
+
|
16
|
+
def hash
|
17
|
+
self.class.hash
|
18
|
+
end
|
19
|
+
|
20
|
+
def ==(other)
|
21
|
+
other.class == self.class
|
22
|
+
end
|
23
|
+
|
24
|
+
alias eql? ==
|
25
|
+
|
26
|
+
def to_s
|
27
|
+
"<% #{self.class} %>"
|
28
|
+
end
|
29
|
+
|
30
|
+
def level
|
31
|
+
[0]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class Not < Base
|
36
|
+
end
|
37
|
+
|
38
|
+
class ReceiverIsNil < Base
|
39
|
+
end
|
40
|
+
|
41
|
+
class ReceiverIsNotNil < Base
|
42
|
+
end
|
43
|
+
|
44
|
+
class ReceiverIsArg < Base
|
45
|
+
end
|
46
|
+
|
47
|
+
class ArgIsReceiver < Base
|
48
|
+
end
|
49
|
+
|
50
|
+
class ArgEqualsReceiver < Base
|
51
|
+
end
|
52
|
+
|
53
|
+
class ArgIsAncestor < Base
|
54
|
+
end
|
55
|
+
|
56
|
+
class Env < Base
|
57
|
+
attr_reader :truthy, :falsy, :type
|
58
|
+
|
59
|
+
def initialize(truthy:, falsy:, type:)
|
60
|
+
@truthy = truthy
|
61
|
+
@falsy = falsy
|
62
|
+
@type = type
|
63
|
+
end
|
64
|
+
|
65
|
+
def ==(other)
|
66
|
+
other.is_a?(Env) && other.truthy == truthy && other.falsy == falsy && other.type == type
|
67
|
+
end
|
68
|
+
|
69
|
+
alias eql? ==
|
70
|
+
|
71
|
+
def hash
|
72
|
+
self.class.hash ^ truthy.hash ^ falsy.hash
|
73
|
+
end
|
74
|
+
|
75
|
+
def inspect
|
76
|
+
"#<Steep::AST::Types::Env @type=#{type}, @truthy=..., @falsy=...>"
|
77
|
+
end
|
78
|
+
|
79
|
+
alias to_s inspect
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
module Steep
|
2
|
+
module AST
|
3
|
+
module Types
|
4
|
+
module Name
|
5
|
+
class Base
|
6
|
+
attr_reader :name
|
7
|
+
|
8
|
+
def initialize(name:)
|
9
|
+
@name = name
|
10
|
+
end
|
11
|
+
|
12
|
+
include Helper::NoFreeVariables
|
13
|
+
|
14
|
+
def subst(s)
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
def level
|
19
|
+
[0]
|
20
|
+
end
|
21
|
+
|
22
|
+
def map_type(&block)
|
23
|
+
self
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class Applying < Base
|
28
|
+
attr_reader :args
|
29
|
+
|
30
|
+
def initialize(name:, args:)
|
31
|
+
super(name: name)
|
32
|
+
@args = args
|
33
|
+
end
|
34
|
+
|
35
|
+
def ==(other)
|
36
|
+
other.class == self.class &&
|
37
|
+
other.name == name &&
|
38
|
+
other.args == args
|
39
|
+
end
|
40
|
+
|
41
|
+
alias eql? ==
|
42
|
+
|
43
|
+
def hash
|
44
|
+
@hash ||= self.class.hash ^ name.hash ^ args.hash
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_s
|
48
|
+
if args.empty?
|
49
|
+
"#{name}"
|
50
|
+
else
|
51
|
+
"#{name}[#{args.join(", ")}]"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def subst(s)
|
56
|
+
if free_variables.intersect?(s.domain)
|
57
|
+
_ = self.class.new(
|
58
|
+
name: name,
|
59
|
+
args: args.map {|a| a.subst(s) }
|
60
|
+
)
|
61
|
+
else
|
62
|
+
self
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def free_variables
|
67
|
+
@fvs ||= Set.new().tap do |set|
|
68
|
+
args.each do |type|
|
69
|
+
set.merge(type.free_variables)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def each_child(&block)
|
75
|
+
if block
|
76
|
+
args.each(&block)
|
77
|
+
else
|
78
|
+
args.each
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
include Helper::ChildrenLevel
|
83
|
+
|
84
|
+
def level
|
85
|
+
[0] + level_of_children(args)
|
86
|
+
end
|
87
|
+
|
88
|
+
def map_type(&block)
|
89
|
+
args = self.args.map(&block)
|
90
|
+
|
91
|
+
_ = self.class.new(name: self.name, args: self.args)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
class Singleton < Base
|
96
|
+
def ==(other)
|
97
|
+
other.class == self.class &&
|
98
|
+
other.name == name
|
99
|
+
end
|
100
|
+
|
101
|
+
alias eql? ==
|
102
|
+
|
103
|
+
def hash
|
104
|
+
self.class.hash ^ name.hash
|
105
|
+
end
|
106
|
+
|
107
|
+
def to_s
|
108
|
+
"singleton(#{name.to_s})"
|
109
|
+
end
|
110
|
+
|
111
|
+
include Helper::NoChild
|
112
|
+
end
|
113
|
+
|
114
|
+
class Instance < Applying
|
115
|
+
def to_module
|
116
|
+
Singleton.new(name: name)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
class Interface < Applying
|
121
|
+
end
|
122
|
+
|
123
|
+
class Alias < Applying
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Steep
|
2
|
+
module AST
|
3
|
+
module Types
|
4
|
+
class Nil
|
5
|
+
extend SharedInstance
|
6
|
+
|
7
|
+
def ==(other)
|
8
|
+
other.is_a?(Nil)
|
9
|
+
end
|
10
|
+
|
11
|
+
def hash
|
12
|
+
self.class.hash
|
13
|
+
end
|
14
|
+
|
15
|
+
alias eql? ==
|
16
|
+
|
17
|
+
def subst(s)
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
"nil"
|
23
|
+
end
|
24
|
+
|
25
|
+
include Helper::NoFreeVariables
|
26
|
+
|
27
|
+
include Helper::NoChild
|
28
|
+
|
29
|
+
def level
|
30
|
+
[0]
|
31
|
+
end
|
32
|
+
|
33
|
+
def back_type
|
34
|
+
Name::Instance.new(name: Builtin::NilClass.module_name,
|
35
|
+
args: [])
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
@@ -0,0 +1,117 @@
|
|
1
|
+
module Steep
|
2
|
+
module AST
|
3
|
+
module Types
|
4
|
+
class Proc
|
5
|
+
attr_reader :type
|
6
|
+
attr_reader :self_type
|
7
|
+
attr_reader :block
|
8
|
+
|
9
|
+
def initialize(type:, block:, self_type:)
|
10
|
+
@type = type
|
11
|
+
@block = block
|
12
|
+
@self_type = self_type
|
13
|
+
end
|
14
|
+
|
15
|
+
def ==(other)
|
16
|
+
other.is_a?(self.class) && other.type == type && other.block == block && other.self_type == self_type
|
17
|
+
end
|
18
|
+
|
19
|
+
def hash
|
20
|
+
self.class.hash ^ type.hash ^ block.hash ^ self_type.hash
|
21
|
+
end
|
22
|
+
|
23
|
+
alias eql? ==
|
24
|
+
|
25
|
+
def subst(s)
|
26
|
+
self.class.new(
|
27
|
+
type: type.subst(s),
|
28
|
+
block: block&.subst(s),
|
29
|
+
self_type: self_type&.subst(s)
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_s
|
34
|
+
s =
|
35
|
+
if self_type
|
36
|
+
"[self: #{self_type}] "
|
37
|
+
end
|
38
|
+
|
39
|
+
if block
|
40
|
+
"^#{type.params} #{s}#{block} -> #{type.return_type}"
|
41
|
+
else
|
42
|
+
"^#{type.params} #{s}-> #{type.return_type}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def free_variables()
|
47
|
+
@fvs ||= Set[].tap do |fvs|
|
48
|
+
fvs.merge(type.free_variables)
|
49
|
+
fvs.merge(block.free_variables) if block
|
50
|
+
fvs.merge(self_type.free_variables) if self_type
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
include Helper::ChildrenLevel
|
55
|
+
|
56
|
+
def level
|
57
|
+
children = type.params&.each_type.to_a + [type.return_type]
|
58
|
+
if block
|
59
|
+
if block.type.params
|
60
|
+
children.push(*block.type.params.each_type.to_a)
|
61
|
+
end
|
62
|
+
children.push(block.type.return_type)
|
63
|
+
end
|
64
|
+
if self_type
|
65
|
+
children.push(self_type)
|
66
|
+
end
|
67
|
+
[0] + level_of_children(children)
|
68
|
+
end
|
69
|
+
|
70
|
+
def map_type(&block)
|
71
|
+
self.class.new(
|
72
|
+
type: type.map_type(&block),
|
73
|
+
block: self.block&.map_type(&block),
|
74
|
+
self_type: self_type ? yield(self_type) : nil
|
75
|
+
)
|
76
|
+
end
|
77
|
+
|
78
|
+
def one_arg?
|
79
|
+
params = type.params
|
80
|
+
if params
|
81
|
+
params.required.size == 1 &&
|
82
|
+
params.optional.empty? &&
|
83
|
+
!params.rest &&
|
84
|
+
params.required_keywords.empty? &&
|
85
|
+
params.optional_keywords.empty? &&
|
86
|
+
!params.rest_keywords
|
87
|
+
else
|
88
|
+
true
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def back_type
|
93
|
+
Name::Instance.new(name: Builtin::Proc.module_name,
|
94
|
+
args: [])
|
95
|
+
end
|
96
|
+
|
97
|
+
def block_required?
|
98
|
+
if block
|
99
|
+
!block.optional?
|
100
|
+
else
|
101
|
+
false
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def each_child(&block)
|
106
|
+
if block
|
107
|
+
type.each_child(&block)
|
108
|
+
self.block&.type&.each_child(&block)
|
109
|
+
self_type.each_child(&block) if self_type
|
110
|
+
else
|
111
|
+
enum_for :each_child
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Steep
|
2
|
+
module AST
|
3
|
+
module Types
|
4
|
+
class Record
|
5
|
+
attr_reader :elements, :required_keys
|
6
|
+
|
7
|
+
def initialize(elements:, required_keys:)
|
8
|
+
@elements = elements
|
9
|
+
@required_keys = required_keys
|
10
|
+
end
|
11
|
+
|
12
|
+
def ==(other)
|
13
|
+
other.is_a?(Record) && other.elements == elements && other.required_keys == required_keys
|
14
|
+
end
|
15
|
+
|
16
|
+
def hash
|
17
|
+
self.class.hash ^ elements.hash ^ required_keys.hash
|
18
|
+
end
|
19
|
+
|
20
|
+
alias eql? ==
|
21
|
+
|
22
|
+
def subst(s)
|
23
|
+
self.class.new(
|
24
|
+
elements: elements.transform_values {|type| type.subst(s) },
|
25
|
+
required_keys: required_keys
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_s
|
30
|
+
strings = elements.keys.sort_by(&:to_s).map do |key|
|
31
|
+
if optional?(key)
|
32
|
+
"?#{key.inspect} => #{elements[key]}"
|
33
|
+
else
|
34
|
+
"#{key.inspect} => #{elements[key]}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
"{ #{strings.join(", ")} }"
|
38
|
+
end
|
39
|
+
|
40
|
+
def free_variables()
|
41
|
+
@fvs ||= Set.new.tap do |set|
|
42
|
+
elements.each_value do |type|
|
43
|
+
set.merge(type.free_variables)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
include Helper::ChildrenLevel
|
49
|
+
|
50
|
+
def each_child(&block)
|
51
|
+
if block
|
52
|
+
elements.each_value(&block)
|
53
|
+
else
|
54
|
+
elements.each_value
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def map_type(&block)
|
59
|
+
self.class.new(
|
60
|
+
elements: elements.transform_values(&block),
|
61
|
+
required_keys: required_keys
|
62
|
+
)
|
63
|
+
end
|
64
|
+
|
65
|
+
def level
|
66
|
+
[0] + level_of_children(elements.values)
|
67
|
+
end
|
68
|
+
|
69
|
+
def required?(key)
|
70
|
+
required_keys.include?(key)
|
71
|
+
end
|
72
|
+
|
73
|
+
def optional?(key)
|
74
|
+
!required_keys.include?(key)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Steep
|
2
|
+
module AST
|
3
|
+
module Types
|
4
|
+
class Self
|
5
|
+
extend SharedInstance
|
6
|
+
|
7
|
+
def ==(other)
|
8
|
+
other.is_a?(Self)
|
9
|
+
end
|
10
|
+
|
11
|
+
def hash
|
12
|
+
self.class.hash
|
13
|
+
end
|
14
|
+
|
15
|
+
alias eql? ==
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
"self"
|
19
|
+
end
|
20
|
+
|
21
|
+
include Helper::NoChild
|
22
|
+
|
23
|
+
def subst(s)
|
24
|
+
if s.self_type
|
25
|
+
s.self_type
|
26
|
+
else
|
27
|
+
self
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
@@fvs = Set[instance]
|
32
|
+
|
33
|
+
def free_variables
|
34
|
+
@@fvs
|
35
|
+
end
|
36
|
+
|
37
|
+
def level
|
38
|
+
[0]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Steep
|
2
|
+
module AST
|
3
|
+
module Types
|
4
|
+
class Top
|
5
|
+
extend SharedInstance
|
6
|
+
|
7
|
+
def ==(other)
|
8
|
+
other.is_a?(Top)
|
9
|
+
end
|
10
|
+
|
11
|
+
def hash
|
12
|
+
self.class.hash
|
13
|
+
end
|
14
|
+
|
15
|
+
alias eql? ==
|
16
|
+
|
17
|
+
def subst(s)
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
"top"
|
23
|
+
end
|
24
|
+
|
25
|
+
include Helper::NoFreeVariables
|
26
|
+
|
27
|
+
include Helper::NoChild
|
28
|
+
|
29
|
+
def level
|
30
|
+
[2]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|