steep 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -1
- data/bin/smoke_runner.rb +1 -1
- data/lib/steep.rb +6 -4
- data/lib/steep/ast/builtin.rb +96 -0
- data/lib/steep/ast/location.rb +9 -5
- data/lib/steep/ast/namespace.rb +80 -0
- data/lib/steep/ast/signature/env.rb +37 -31
- data/lib/steep/ast/types/boolean.rb +2 -2
- data/lib/steep/ast/types/hash.rb +50 -0
- data/lib/steep/ast/types/literal.rb +12 -10
- data/lib/steep/ast/types/name.rb +135 -94
- data/lib/steep/ast/types/nil.rb +3 -1
- data/lib/steep/ast/types/proc.rb +3 -1
- data/lib/steep/drivers/check.rb +4 -4
- data/lib/steep/drivers/utils/validator.rb +11 -16
- data/lib/steep/interface/builder.rb +201 -146
- data/lib/steep/interface/instantiated.rb +8 -0
- data/lib/steep/names.rb +86 -0
- data/lib/steep/parser.y +1093 -668
- data/lib/steep/source.rb +2 -2
- data/lib/steep/subtyping/check.rb +199 -63
- data/lib/steep/subtyping/constraints.rb +2 -5
- data/lib/steep/subtyping/variable_variance.rb +2 -2
- data/lib/steep/type_construction.rb +194 -175
- data/lib/steep/type_inference/block_params.rb +9 -21
- data/lib/steep/type_inference/constant_env.rb +26 -30
- data/lib/steep/type_inference/send_args.rb +4 -7
- data/lib/steep/type_inference/type_env.rb +3 -3
- data/lib/steep/version.rb +1 -1
- data/smoke/alias/a.rb +1 -1
- data/smoke/alias/b.rb +1 -1
- data/smoke/class/i.rbi +1 -1
- data/smoke/hash/a.rbi +8 -0
- data/smoke/hash/c.rb +18 -0
- data/smoke/hash/d.rb +6 -0
- data/smoke/hello/hello.rb +2 -2
- data/smoke/interface/a.rb +14 -0
- data/smoke/interface/a.rbi +12 -0
- data/smoke/module/a.rb +1 -1
- data/smoke/module/a.rbi +3 -3
- data/smoke/module/b.rb +1 -1
- data/smoke/stdout/a.rb +2 -2
- data/stdlib/builtin.rbi +6 -7
- data/steep.gemspec +1 -1
- metadata +14 -7
- data/lib/steep/module_name.rb +0 -116
- data/lib/steep/type_name.rb +0 -93
@@ -149,13 +149,13 @@ module Steep
|
|
149
149
|
type = params_type.required[0]
|
150
150
|
|
151
151
|
case
|
152
|
-
when
|
152
|
+
when AST::Builtin::Array.instance_type?(type)
|
153
153
|
type_arg = type.args[0]
|
154
154
|
params.each do |param|
|
155
155
|
unless param == rest_param
|
156
|
-
zip << [param, AST::Types::Union.build(types: [type_arg, AST::
|
156
|
+
zip << [param, AST::Types::Union.build(types: [type_arg, AST::Builtin.nil_type])]
|
157
157
|
else
|
158
|
-
zip << [param, AST::
|
158
|
+
zip << [param, AST::Builtin::Array.instance_type(type_arg)]
|
159
159
|
end
|
160
160
|
end
|
161
161
|
when type.is_a?(AST::Types::Tuple)
|
@@ -172,7 +172,7 @@ module Steep
|
|
172
172
|
if rest_param
|
173
173
|
if types.any?
|
174
174
|
union = AST::Types::Union.build(types: types)
|
175
|
-
zip << [rest_param, AST::
|
175
|
+
zip << [rest_param, AST::Builtin::Array.instance_type(union)]
|
176
176
|
else
|
177
177
|
zip << [rest_param, AST::Types::Nil.new]
|
178
178
|
end
|
@@ -187,23 +187,17 @@ module Steep
|
|
187
187
|
if type
|
188
188
|
zip << [param, type]
|
189
189
|
else
|
190
|
-
zip << [param, AST::
|
190
|
+
zip << [param, AST::Builtin.nil_type]
|
191
191
|
end
|
192
192
|
end
|
193
193
|
|
194
194
|
if rest_param
|
195
195
|
if types.empty?
|
196
|
-
array = AST::
|
197
|
-
name: "::Array",
|
198
|
-
args: [params_type.rest || AST::Types::Any.new]
|
199
|
-
)
|
196
|
+
array = AST::Builtin::Array.instance_type(params_type.rest || AST::Builtin.any_type)
|
200
197
|
zip << [rest_param, array]
|
201
198
|
else
|
202
199
|
union = AST::Types::Union.build(types: types.map(&:last) + [params_type.rest])
|
203
|
-
array = AST::
|
204
|
-
name: "::Array",
|
205
|
-
args: [union]
|
206
|
-
)
|
200
|
+
array = AST::Builtin::Array.instance_type(union)
|
207
201
|
zip << [rest_param, array]
|
208
202
|
end
|
209
203
|
end
|
@@ -211,19 +205,13 @@ module Steep
|
|
211
205
|
end
|
212
206
|
end
|
213
207
|
|
214
|
-
def array?(type)
|
215
|
-
type.is_a?(AST::Types::Name) &&
|
216
|
-
type.name.is_a?(TypeName::Instance) &&
|
217
|
-
type.name.name.name == "Array" && type.name.name.absolute?
|
218
|
-
end
|
219
|
-
|
220
208
|
def expandable_params?(params_type)
|
221
209
|
if params_type.flat_unnamed_params.size == 1
|
222
210
|
case (type = params_type.required.first)
|
223
211
|
when AST::Types::Tuple
|
224
212
|
true
|
225
|
-
when AST::Types::Name
|
226
|
-
|
213
|
+
when AST::Types::Name::Base
|
214
|
+
AST::Builtin::Array.instance_type?(type)
|
227
215
|
end
|
228
216
|
end
|
229
217
|
end
|
@@ -2,51 +2,47 @@ module Steep
|
|
2
2
|
module TypeInference
|
3
3
|
class ConstantEnv
|
4
4
|
attr_reader :builder
|
5
|
-
attr_reader :
|
5
|
+
attr_reader :context
|
6
6
|
attr_reader :cache
|
7
7
|
|
8
|
-
|
8
|
+
# ConstantEnv receives an optional Names::Module, not a Namespace, because this is a simulation of Ruby.
|
9
|
+
# Any namespace is a module or class.
|
10
|
+
def initialize(builder:, context:)
|
9
11
|
@cache = {}
|
10
12
|
@builder = builder
|
11
|
-
@
|
13
|
+
@context = context
|
12
14
|
end
|
13
15
|
|
14
16
|
def signatures
|
15
17
|
builder.signatures
|
16
18
|
end
|
17
19
|
|
18
|
-
def
|
19
|
-
|
20
|
-
|
21
|
-
|
20
|
+
def namespace
|
21
|
+
@namespace ||= if context
|
22
|
+
context.namespace.append(context.name)
|
23
|
+
else
|
24
|
+
AST::Namespace.root
|
25
|
+
end
|
26
|
+
end
|
22
27
|
|
23
|
-
|
28
|
+
def lookup(name)
|
29
|
+
cache[name] ||= lookup0(name, namespace: namespace)
|
24
30
|
end
|
25
31
|
|
32
|
+
# @type method lookup0: (Names::Module, namespace: AST::Namespace) -> Type
|
26
33
|
def lookup0(name, namespace:)
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
34
|
+
full_name = name.in_namespace(namespace)
|
35
|
+
case
|
36
|
+
when signatures.module_name?(full_name)
|
37
|
+
AST::Types::Name::Module.new(name: full_name)
|
38
|
+
when signatures.class_name?(full_name)
|
39
|
+
AST::Types::Name::Class.new(name: full_name, constructor: true)
|
40
|
+
when signatures.const_name?(full_name)
|
41
|
+
builder.absolute_type(signatures.find_const(name, current_module: namespace).type,
|
42
|
+
current: namespace)
|
36
43
|
else
|
37
|
-
|
38
|
-
|
39
|
-
when signatures.module_name?(name, current_module: namespace)
|
40
|
-
AST::Types::Name.new_module(name: namespace + name)
|
41
|
-
when signatures.class_name?(name, current_module: namespace)
|
42
|
-
AST::Types::Name.new_class(name: namespace + name, constructor: true)
|
43
|
-
when signatures.const_name?(name, current_module: namespace)
|
44
|
-
builder.absolute_type(signatures.find_const(name, current_module: namespace).type, current: nil)
|
45
|
-
else
|
46
|
-
lookup0(name, namespace: namespace.parent)
|
47
|
-
end
|
48
|
-
else
|
49
|
-
lookup0(name.absolute!, namespace: nil)
|
44
|
+
unless namespace.empty?
|
45
|
+
lookup0(name, namespace: namespace.parent)
|
50
46
|
end
|
51
47
|
end
|
52
48
|
end
|
@@ -123,12 +123,9 @@ module Steep
|
|
123
123
|
|
124
124
|
if kwsplat_nodes.any?
|
125
125
|
pairs << [kw_args,
|
126
|
-
AST::
|
127
|
-
|
128
|
-
|
129
|
-
AST::Types::Name.new_instance(name: "::Symbol"),
|
130
|
-
AST::Types::Union.build(types: rest_types + [params.rest_keywords])
|
131
|
-
]
|
126
|
+
AST::Builtin::Hash.instance_type(
|
127
|
+
AST::Builtin::Symbol.instance_type,
|
128
|
+
AST::Types::Union.build(types: rest_types + [params.rest_keywords])
|
132
129
|
)]
|
133
130
|
end
|
134
131
|
end
|
@@ -185,7 +182,7 @@ module Steep
|
|
185
182
|
|
186
183
|
if types
|
187
184
|
if arg.type == :splat
|
188
|
-
type = AST::
|
185
|
+
type = AST::Builtin::Array.instance_type(AST::Types::Union.build(types: types))
|
189
186
|
else
|
190
187
|
type = AST::Types::Union.build(types: types)
|
191
188
|
end
|
@@ -38,7 +38,7 @@ module Steep
|
|
38
38
|
env.set(const: name, type: type)
|
39
39
|
end
|
40
40
|
signatures.globals.each do |name, annot|
|
41
|
-
type = subtyping.builder.absolute_type(annot.type, current:
|
41
|
+
type = subtyping.builder.absolute_type(annot.type, current: AST::Namespace.root)
|
42
42
|
env.set(gvar: name, type: type)
|
43
43
|
end
|
44
44
|
end
|
@@ -83,7 +83,7 @@ module Steep
|
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
-
# @type method assert: (const:
|
86
|
+
# @type method assert: (const: Names::Module) { () -> void } -> AST::Type
|
87
87
|
# | (gvar: Symbol) { () -> void } -> AST::Type
|
88
88
|
# | (ivar: Symbol) { () -> void } -> AST::Type
|
89
89
|
# | (lvar: Symbol) { () -> AST::Type | nil } -> AST::Type
|
@@ -138,7 +138,7 @@ module Steep
|
|
138
138
|
end
|
139
139
|
end
|
140
140
|
|
141
|
-
# @type method assign: (const:
|
141
|
+
# @type method assign: (const: Names::Module, type: AST::Type) { (Subtyping::Result::Failure | nil) -> void } -> AST::Type
|
142
142
|
# | (gvar: Symbol, type: AST::Type) { (Subtyping::Result::Failure | nil) -> void } -> AST::Type
|
143
143
|
# | (ivar: Symbol, type: AST::Type) { (Subtyping::Result::Failure | nil) -> void } -> AST::Type
|
144
144
|
# | (lvar: Symbol | LabeledName, type: AST::Type) { (Subtyping::Result::Failure) -> void } -> AST::Type
|
data/lib/steep/version.rb
CHANGED
data/smoke/alias/a.rb
CHANGED
data/smoke/alias/b.rb
CHANGED
data/smoke/class/i.rbi
CHANGED
data/smoke/hash/a.rbi
ADDED
data/smoke/hash/c.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# @type var params: t
|
2
|
+
params = _ = nil
|
3
|
+
|
4
|
+
id = params[:id]
|
5
|
+
# !expects NoMethodError: type=::Integer, method=abcdefg
|
6
|
+
id.abcdefg
|
7
|
+
|
8
|
+
name = params[:name]
|
9
|
+
# !expects NoMethodError: type=::String, method=abcdefg
|
10
|
+
name.abcdefg
|
11
|
+
|
12
|
+
# !expects NoMethodError: type=(::Integer | ::String | nil), method=abcdefg
|
13
|
+
params[(_=nil) ? :id : :name].abcdefg
|
14
|
+
|
15
|
+
# @type var controller: Controller
|
16
|
+
controller = _ = nil
|
17
|
+
|
18
|
+
controller.params[:id] + 3
|
data/smoke/hash/d.rb
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
# @type var params: { name: String, id: Integer }
|
2
|
+
|
3
|
+
params = { id: 30, name: "Matz" }
|
4
|
+
|
5
|
+
# !expects IncompatibleAssignment: lhs_type={ :name => ::String, :id => ::Integer }, rhs_type=::Hash<::Symbol, ::String>
|
6
|
+
params = { id: "30", name: "foo", email: "matsumoto@soutaro.com" }
|
data/smoke/hello/hello.rb
CHANGED
@@ -6,8 +6,8 @@ y = (_ = nil)
|
|
6
6
|
|
7
7
|
a = x.foo
|
8
8
|
|
9
|
-
# !expects NoMethodError: type
|
9
|
+
# !expects NoMethodError: type=::_Bar, method=foo
|
10
10
|
b = y.foo
|
11
11
|
|
12
|
-
# !expects IncompatibleAssignment: lhs_type
|
12
|
+
# !expects IncompatibleAssignment: lhs_type=::_Foo, rhs_type=::_Bar
|
13
13
|
x = y
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class A
|
2
|
+
# @dynamic foo
|
3
|
+
|
4
|
+
def hello
|
5
|
+
# !expects NoMethodError: type=::A::Object, method=bar
|
6
|
+
foo.foo.bar
|
7
|
+
|
8
|
+
# @type var object: ::Object
|
9
|
+
object = _ = nil
|
10
|
+
|
11
|
+
# !expects NoMethodError: type=::Object, method=object?
|
12
|
+
object.object?
|
13
|
+
end
|
14
|
+
end
|
data/smoke/module/a.rb
CHANGED
@@ -13,7 +13,7 @@ module A
|
|
13
13
|
# !expects IncompatibleAssignment: lhs_type=::String, rhs_type=::Integer
|
14
14
|
s = n
|
15
15
|
|
16
|
-
# !expects NoMethodError: type=(::A & ::Object & _Each<::Integer>), method=foo
|
16
|
+
# !expects NoMethodError: type=(::A & ::Object & ::_Each<::Integer, ::A>), method=foo
|
17
17
|
foo()
|
18
18
|
|
19
19
|
n
|
data/smoke/module/a.rbi
CHANGED
data/smoke/module/b.rb
CHANGED
data/smoke/stdout/a.rb
CHANGED
data/stdlib/builtin.rbi
CHANGED
@@ -2,7 +2,7 @@ class BasicObject
|
|
2
2
|
def __id__: -> Integer
|
3
3
|
end
|
4
4
|
|
5
|
-
class Object
|
5
|
+
class Object < BasicObject
|
6
6
|
include Kernel
|
7
7
|
def tap: { (self) -> any } -> self
|
8
8
|
def to_s: -> String
|
@@ -43,8 +43,7 @@ end
|
|
43
43
|
class Method
|
44
44
|
end
|
45
45
|
|
46
|
-
class Class<
|
47
|
-
def new: (*any, **any) -> 'instance
|
46
|
+
class Class < Module
|
48
47
|
def class: -> Class.class
|
49
48
|
def allocate: -> any
|
50
49
|
end
|
@@ -268,7 +267,7 @@ class Numeric
|
|
268
267
|
def -@: -> self
|
269
268
|
end
|
270
269
|
|
271
|
-
class Integer
|
270
|
+
class Integer < Numeric
|
272
271
|
def to_int: -> Integer
|
273
272
|
def +: (Integer) -> Integer
|
274
273
|
| (Numeric) -> Numeric
|
@@ -296,7 +295,7 @@ class Integer <: Numeric
|
|
296
295
|
def ~: () -> Integer
|
297
296
|
end
|
298
297
|
|
299
|
-
class Float
|
298
|
+
class Float < Numeric
|
300
299
|
def *: (Float) -> Float
|
301
300
|
| (Integer) -> Float
|
302
301
|
| (Numeric) -> Numeric
|
@@ -313,7 +312,7 @@ end
|
|
313
312
|
|
314
313
|
Math::PI: Float
|
315
314
|
|
316
|
-
class Complex
|
315
|
+
class Complex < Numeric
|
317
316
|
def self.polar: (Numeric, Numeric) -> instance
|
318
317
|
def +: (Complex) -> Complex
|
319
318
|
| (Numeric) -> Numeric
|
@@ -572,7 +571,7 @@ end
|
|
572
571
|
|
573
572
|
File::FNM_DOTMATCH: Integer
|
574
573
|
|
575
|
-
class File
|
574
|
+
class File < IO
|
576
575
|
def self.binread: (String) -> String
|
577
576
|
def self.extname: (String) -> String
|
578
577
|
def self.basename: (String) -> String
|
data/steep.gemspec
CHANGED
@@ -30,7 +30,7 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.add_development_dependency "racc", "~> 1.4"
|
31
31
|
|
32
32
|
spec.add_runtime_dependency "parser", "~> 2.4"
|
33
|
-
spec.add_runtime_dependency "ast_utils", "~> 0.
|
33
|
+
spec.add_runtime_dependency "ast_utils", "~> 0.3.0"
|
34
34
|
spec.add_runtime_dependency "activesupport", "~> 5.1"
|
35
35
|
spec.add_runtime_dependency "rainbow", "~> 2.2.2", "< 4.0"
|
36
36
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: steep
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Soutaro Matsumoto
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-09-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -86,14 +86,14 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 0.
|
89
|
+
version: 0.3.0
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 0.
|
96
|
+
version: 0.3.0
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: activesupport
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -151,8 +151,10 @@ files:
|
|
151
151
|
- lib/steep/ast/annotation.rb
|
152
152
|
- lib/steep/ast/annotation/collection.rb
|
153
153
|
- lib/steep/ast/buffer.rb
|
154
|
+
- lib/steep/ast/builtin.rb
|
154
155
|
- lib/steep/ast/location.rb
|
155
156
|
- lib/steep/ast/method_type.rb
|
157
|
+
- lib/steep/ast/namespace.rb
|
156
158
|
- lib/steep/ast/signature/alias.rb
|
157
159
|
- lib/steep/ast/signature/class.rb
|
158
160
|
- lib/steep/ast/signature/const.rb
|
@@ -167,6 +169,7 @@ files:
|
|
167
169
|
- lib/steep/ast/types/boolean.rb
|
168
170
|
- lib/steep/ast/types/bot.rb
|
169
171
|
- lib/steep/ast/types/class.rb
|
172
|
+
- lib/steep/ast/types/hash.rb
|
170
173
|
- lib/steep/ast/types/helper.rb
|
171
174
|
- lib/steep/ast/types/instance.rb
|
172
175
|
- lib/steep/ast/types/intersection.rb
|
@@ -196,7 +199,7 @@ files:
|
|
196
199
|
- lib/steep/interface/method.rb
|
197
200
|
- lib/steep/interface/method_type.rb
|
198
201
|
- lib/steep/interface/substitution.rb
|
199
|
-
- lib/steep/
|
202
|
+
- lib/steep/names.rb
|
200
203
|
- lib/steep/parser.rb
|
201
204
|
- lib/steep/parser.y
|
202
205
|
- lib/steep/signature/errors.rb
|
@@ -214,7 +217,6 @@ files:
|
|
214
217
|
- lib/steep/type_inference/constant_env.rb
|
215
218
|
- lib/steep/type_inference/send_args.rb
|
216
219
|
- lib/steep/type_inference/type_env.rb
|
217
|
-
- lib/steep/type_name.rb
|
218
220
|
- lib/steep/typing.rb
|
219
221
|
- lib/steep/version.rb
|
220
222
|
- manual/annotations.md
|
@@ -258,7 +260,10 @@ files:
|
|
258
260
|
- smoke/extension/c.rb
|
259
261
|
- smoke/extension/d.rb
|
260
262
|
- smoke/hash/a.rb
|
263
|
+
- smoke/hash/a.rbi
|
261
264
|
- smoke/hash/b.rb
|
265
|
+
- smoke/hash/c.rb
|
266
|
+
- smoke/hash/d.rb
|
262
267
|
- smoke/hello/hello.rb
|
263
268
|
- smoke/hello/hello.rbi
|
264
269
|
- smoke/if/a.rb
|
@@ -266,6 +271,8 @@ files:
|
|
266
271
|
- smoke/implements/a.rbi
|
267
272
|
- smoke/initialize/a.rb
|
268
273
|
- smoke/initialize/a.rbi
|
274
|
+
- smoke/interface/a.rb
|
275
|
+
- smoke/interface/a.rbi
|
269
276
|
- smoke/kwbegin/a.rb
|
270
277
|
- smoke/lambda/a.rb
|
271
278
|
- smoke/literal/a.rb
|
@@ -317,7 +324,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
317
324
|
version: '0'
|
318
325
|
requirements: []
|
319
326
|
rubyforge_project:
|
320
|
-
rubygems_version: 2.7.
|
327
|
+
rubygems_version: 2.7.6
|
321
328
|
signing_key:
|
322
329
|
specification_version: 4
|
323
330
|
summary: Gradual Typing for Ruby
|