steep 0.5.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|