steep 0.9.0 → 0.10.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 +8 -1
- data/lib/steep/ast/types/proc.rb +1 -1
- data/lib/steep/cli.rb +25 -4
- data/lib/steep/drivers/annotations.rb +14 -3
- data/lib/steep/drivers/check.rb +71 -75
- data/lib/steep/drivers/print_interface.rb +56 -25
- data/lib/steep/drivers/scaffold.rb +7 -4
- data/lib/steep/drivers/utils/each_signature.rb +6 -41
- data/lib/steep/drivers/validate.rb +35 -10
- data/lib/steep/drivers/watch.rb +188 -0
- data/lib/steep/errors.rb +2 -2
- data/lib/steep/project/file.rb +119 -0
- data/lib/steep/project/listener.rb +53 -0
- data/lib/steep/project/options.rb +13 -0
- data/lib/steep/project.rb +231 -0
- data/lib/steep/type_construction.rb +56 -29
- data/lib/steep/version.rb +1 -1
- data/lib/steep.rb +7 -1
- data/sig/project.rbi +106 -0
- data/smoke/hash/f.rb +11 -0
- data/stdlib/builtin.rbi +3 -0
- data/steep.gemspec +3 -1
- metadata +39 -7
- data/lib/steep/drivers/utils/validator.rb +0 -110
- data/sig/signature.rbi +0 -146
- data/sig/types.rbi +0 -43
@@ -50,8 +50,9 @@ module Steep
|
|
50
50
|
attr_reader :const_env
|
51
51
|
attr_reader :implement_name
|
52
52
|
attr_reader :current_namespace
|
53
|
+
attr_reader :class_name
|
53
54
|
|
54
|
-
def initialize(instance_type:, module_type:, implement_name:, current_namespace:, const_env:)
|
55
|
+
def initialize(instance_type:, module_type:, implement_name:, current_namespace:, const_env:, class_name:)
|
55
56
|
@instance_type = instance_type
|
56
57
|
@module_type = module_type
|
57
58
|
@defined_instance_methods = Set.new
|
@@ -59,6 +60,7 @@ module Steep
|
|
59
60
|
@implement_name = implement_name
|
60
61
|
@current_namespace = current_namespace
|
61
62
|
@const_env = const_env
|
63
|
+
@class_name = class_name
|
62
64
|
end
|
63
65
|
|
64
66
|
def const_context
|
@@ -344,7 +346,8 @@ module Steep
|
|
344
346
|
module_type: annots.self_type || module_type,
|
345
347
|
implement_name: implement_module_name,
|
346
348
|
current_namespace: new_namespace,
|
347
|
-
const_env: module_const_env
|
349
|
+
const_env: module_const_env,
|
350
|
+
class_name: absolute_name(new_module_name)
|
348
351
|
)
|
349
352
|
|
350
353
|
module_type_env = TypeInference::TypeEnv.build(annotations: annots,
|
@@ -368,6 +371,7 @@ module Steep
|
|
368
371
|
|
369
372
|
def for_class(node)
|
370
373
|
new_class_name = Names::Module.from_node(node.children.first) or raise "Unexpected class name: #{node.children.first}"
|
374
|
+
super_class_name = node.children[1] && Names::Module.from_node(node.children[1])
|
371
375
|
new_namespace = nested_namespace_for_module(new_class_name)
|
372
376
|
|
373
377
|
annots = source.annotations(block: node, builder: checker.builder, current_module: new_namespace)
|
@@ -384,16 +388,26 @@ module Steep
|
|
384
388
|
end
|
385
389
|
end
|
386
390
|
else
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
391
|
+
name = nil
|
392
|
+
name ||= absolute_name(new_class_name).yield_self do |absolute_name|
|
393
|
+
absolute_name if checker.builder.signatures.class_name?(absolute_name)
|
394
|
+
end
|
395
|
+
name ||= super_class_name && absolute_name(super_class_name).yield_self do |absolute_name|
|
396
|
+
absolute_name if checker.builder.signatures.class_name?(absolute_name)
|
397
|
+
end
|
398
|
+
|
399
|
+
if name
|
400
|
+
signature = checker.builder.signatures.find_class(name)
|
401
|
+
AST::Annotation::Implements::Module.new(name: name,
|
402
|
+
args: signature.params&.variables || [])
|
393
403
|
end
|
394
404
|
end
|
395
405
|
end
|
396
406
|
|
407
|
+
if annots.implement_module_annotation
|
408
|
+
new_class_name = implement_module_name.name
|
409
|
+
end
|
410
|
+
|
397
411
|
if implement_module_name
|
398
412
|
class_name = implement_module_name.name
|
399
413
|
class_args = implement_module_name.args.map {|x| AST::Types::Var.new(name: x) }
|
@@ -416,7 +430,8 @@ module Steep
|
|
416
430
|
module_type: annots.self_type || annots.module_type || module_type,
|
417
431
|
implement_name: implement_module_name,
|
418
432
|
current_namespace: new_namespace,
|
419
|
-
const_env: class_const_env
|
433
|
+
const_env: class_const_env,
|
434
|
+
class_name: absolute_name(new_class_name)
|
420
435
|
)
|
421
436
|
|
422
437
|
class_type_env = TypeInference::TypeEnv.build(
|
@@ -702,7 +717,7 @@ module Steep
|
|
702
717
|
if send_node.type == :lambda
|
703
718
|
type_lambda(node, block_params: params, block_body: body, type_hint: hint)
|
704
719
|
else
|
705
|
-
type_send(node, send_node: send_node, block_params: params, block_body: body)
|
720
|
+
type_send(node, send_node: send_node, block_params: params, block_body: body, unwrap: send_node.type == :csend)
|
706
721
|
end
|
707
722
|
end
|
708
723
|
|
@@ -1151,11 +1166,12 @@ module Steep
|
|
1151
1166
|
expand_alias(hint) do |hint|
|
1152
1167
|
is_tuple = hint.is_a?(AST::Types::Tuple)
|
1153
1168
|
is_tuple &&= node.children.all? {|child| child.type != :splat }
|
1154
|
-
is_tuple &&= node.children.
|
1155
|
-
|
1156
|
-
|
1157
|
-
|
1158
|
-
|
1169
|
+
is_tuple &&= node.children.size >= hint.types.size
|
1170
|
+
is_tuple &&= hint.types.map.with_index do |child_type, index|
|
1171
|
+
child_node = node.children[index]
|
1172
|
+
[synthesize(child_node, hint: child_type), child_type]
|
1173
|
+
end.all? do |node_type, hint_type|
|
1174
|
+
relation = Subtyping::Relation.new(sub_type: node_type, super_type: hint_type)
|
1159
1175
|
result = checker.check(relation, constraints: Subtyping::Constraints.empty)
|
1160
1176
|
result.success?
|
1161
1177
|
end
|
@@ -1224,7 +1240,9 @@ module Steep
|
|
1224
1240
|
|
1225
1241
|
when :or
|
1226
1242
|
yield_self do
|
1227
|
-
|
1243
|
+
c1, c2 = node.children
|
1244
|
+
t1 = synthesize(c1, hint: hint)
|
1245
|
+
t2 = synthesize(c2, hint: unwrap(t1))
|
1228
1246
|
type = union_type(unwrap(t1), t2)
|
1229
1247
|
typing.add_typing(node, type)
|
1230
1248
|
end
|
@@ -1272,7 +1290,7 @@ module Steep
|
|
1272
1290
|
if (body = clause.children.last)
|
1273
1291
|
if var_names && var_types && test_types.all? {|type| type.is_a?(AST::Types::Name::Class) }
|
1274
1292
|
var_types_in_body = test_types.flat_map {|test_type|
|
1275
|
-
filtered_types = var_types.select {|var_type| var_type.name == test_type.name }
|
1293
|
+
filtered_types = var_types.select {|var_type| var_type.is_a?(AST::Types::Name::Base) && var_type.name == test_type.name }
|
1276
1294
|
if filtered_types.empty?
|
1277
1295
|
to_instance_type(test_type)
|
1278
1296
|
else
|
@@ -1281,7 +1299,7 @@ module Steep
|
|
1281
1299
|
}
|
1282
1300
|
var_types.reject! {|type|
|
1283
1301
|
var_types_in_body.any? {|test_type|
|
1284
|
-
test_type.name == type.name
|
1302
|
+
type.is_a?(AST::Types::Name::Base) && test_type.name == type.name
|
1285
1303
|
}
|
1286
1304
|
}
|
1287
1305
|
|
@@ -1761,7 +1779,7 @@ module Steep
|
|
1761
1779
|
receiver_type = unwrap(receiver_type)
|
1762
1780
|
end
|
1763
1781
|
|
1764
|
-
return_type = case receiver_type
|
1782
|
+
return_type = case expand_alias(receiver_type)
|
1765
1783
|
when AST::Types::Any
|
1766
1784
|
typing.add_typing node, AST::Builtin.any_type
|
1767
1785
|
|
@@ -2041,7 +2059,7 @@ module Steep
|
|
2041
2059
|
)
|
2042
2060
|
else
|
2043
2061
|
hash_elements = params.required_keywords.merge(
|
2044
|
-
method_type.optional_keywords.transform_values do |type|
|
2062
|
+
method_type.params.optional_keywords.transform_values do |type|
|
2045
2063
|
AST::Types::Union.build(types: [type, AST::Builtin.nil_type],
|
2046
2064
|
location: method_type.location)
|
2047
2065
|
end
|
@@ -2465,10 +2483,12 @@ module Steep
|
|
2465
2483
|
when annotations.instance_dynamics.include?(method_name)
|
2466
2484
|
# ok
|
2467
2485
|
else
|
2468
|
-
|
2469
|
-
|
2470
|
-
|
2471
|
-
|
2486
|
+
if module_name.name == module_context&.class_name
|
2487
|
+
typing.add_error Errors::MethodDefinitionMissing.new(node: node,
|
2488
|
+
module_name: module_name.name,
|
2489
|
+
kind: :instance,
|
2490
|
+
missing_method: method_name)
|
2491
|
+
end
|
2472
2492
|
end
|
2473
2493
|
end
|
2474
2494
|
expected_module_method_names.each do |method_name|
|
@@ -2478,10 +2498,12 @@ module Steep
|
|
2478
2498
|
when annotations.module_dynamics.include?(method_name)
|
2479
2499
|
# ok
|
2480
2500
|
else
|
2481
|
-
|
2482
|
-
|
2483
|
-
|
2484
|
-
|
2501
|
+
if module_name.name == module_context&.class_name
|
2502
|
+
typing.add_error Errors::MethodDefinitionMissing.new(node: node,
|
2503
|
+
module_name: module_name.name,
|
2504
|
+
kind: :module,
|
2505
|
+
missing_method: method_name)
|
2506
|
+
end
|
2485
2507
|
end
|
2486
2508
|
end
|
2487
2509
|
|
@@ -2659,7 +2681,8 @@ module Steep
|
|
2659
2681
|
end
|
2660
2682
|
|
2661
2683
|
def try_hash_type(node, hint)
|
2662
|
-
|
2684
|
+
case hint
|
2685
|
+
when AST::Types::Record
|
2663
2686
|
typing.new_child do |child_typing|
|
2664
2687
|
new_construction = with_new_typing(child_typing)
|
2665
2688
|
elements = {}
|
@@ -2699,6 +2722,10 @@ module Steep
|
|
2699
2722
|
hash = AST::Types::Record.new(elements: elements)
|
2700
2723
|
typing.add_typing(node, hash)
|
2701
2724
|
end
|
2725
|
+
when AST::Types::Union
|
2726
|
+
hint.types.find do |type|
|
2727
|
+
try_hash_type(node, type)
|
2728
|
+
end
|
2702
2729
|
end
|
2703
2730
|
end
|
2704
2731
|
end
|
data/lib/steep/version.rb
CHANGED
data/lib/steep.rb
CHANGED
@@ -7,6 +7,8 @@ require "active_support/core_ext/object/try"
|
|
7
7
|
require "logger"
|
8
8
|
require "active_support/tagged_logging"
|
9
9
|
require "rainbow"
|
10
|
+
require "listen"
|
11
|
+
require 'pry'
|
10
12
|
|
11
13
|
require "steep/ast/namespace"
|
12
14
|
require "steep/names"
|
@@ -72,13 +74,17 @@ require "steep/type_inference/block_params"
|
|
72
74
|
require "steep/type_inference/constant_env"
|
73
75
|
require "steep/type_inference/type_env"
|
74
76
|
|
75
|
-
require "steep/
|
77
|
+
require "steep/project"
|
78
|
+
require "steep/project/file"
|
79
|
+
require "steep/project/listener"
|
80
|
+
require "steep/project/options"
|
76
81
|
require "steep/drivers/utils/each_signature"
|
77
82
|
require "steep/drivers/check"
|
78
83
|
require "steep/drivers/validate"
|
79
84
|
require "steep/drivers/annotations"
|
80
85
|
require "steep/drivers/scaffold"
|
81
86
|
require "steep/drivers/print_interface"
|
87
|
+
require "steep/drivers/watch"
|
82
88
|
|
83
89
|
if ENV["NO_COLOR"]
|
84
90
|
Rainbow.enabled = false
|
data/sig/project.rbi
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
class Pathname
|
2
|
+
end
|
3
|
+
|
4
|
+
class Time
|
5
|
+
def self.now: -> instance
|
6
|
+
def < : (Time) -> bool
|
7
|
+
def >=: (Time) -> bool
|
8
|
+
end
|
9
|
+
|
10
|
+
type annotation = any
|
11
|
+
|
12
|
+
class Steep::Source
|
13
|
+
def self.parse: (String, path: String, labeling: any) -> instance
|
14
|
+
def annotations: (block: any, builder: any, current_module: any) -> Array<annotation>
|
15
|
+
def node: -> any
|
16
|
+
end
|
17
|
+
|
18
|
+
class Steep::Typing
|
19
|
+
attr_reader errors: Array<type_error>
|
20
|
+
attr_reader nodes: any
|
21
|
+
end
|
22
|
+
|
23
|
+
type type_error = any
|
24
|
+
|
25
|
+
class Steep::Project::Options
|
26
|
+
attr_accessor fallback_any_is_error: bool
|
27
|
+
attr_accessor allow_missing_definitions: bool
|
28
|
+
end
|
29
|
+
|
30
|
+
class Parser::SyntaxError
|
31
|
+
end
|
32
|
+
|
33
|
+
class Steep::Project::SourceFile
|
34
|
+
attr_reader options: Options
|
35
|
+
attr_reader path: Pathname
|
36
|
+
attr_accessor content: String
|
37
|
+
attr_reader content_updated_at: Time
|
38
|
+
|
39
|
+
attr_reader source: (Source | Parser::SyntaxError | nil)
|
40
|
+
attr_reader typing: Typing?
|
41
|
+
attr_reader last_type_checked_at: Time?
|
42
|
+
|
43
|
+
def initialize: (path: Pathname, options: Options) -> any
|
44
|
+
def requires_type_check?: -> bool
|
45
|
+
def invalidate: -> void
|
46
|
+
def parse: -> (Source | Parser::SyntaxError)
|
47
|
+
def errors: -> Array<type_error>?
|
48
|
+
def type_check: (any) -> void
|
49
|
+
end
|
50
|
+
|
51
|
+
class Steep::Project::SignatureFile
|
52
|
+
attr_reader path: Pathname
|
53
|
+
attr_accessor content: String
|
54
|
+
attr_reader content_updated_at: Time
|
55
|
+
|
56
|
+
def parse: -> Array<any>
|
57
|
+
end
|
58
|
+
|
59
|
+
interface Steep::Project::_Listener
|
60
|
+
def parse_signature: <'x> (project: Project, file: SignatureFile) { -> 'x } -> 'x
|
61
|
+
def parse_source: <'x> (project: Project, file: SourceFile) { -> 'x } -> 'x
|
62
|
+
def check: <'x> (project: Project) { -> 'x } -> 'x
|
63
|
+
def load_signature: <'x> (project: Project) { -> 'x } -> 'x
|
64
|
+
def validate_signature: <'x> (project: Project) { -> 'x } -> 'x
|
65
|
+
def type_check_source: <'x> (project: Project, file: SourceFile) { -> 'x } -> 'x
|
66
|
+
def clear_project: <'x> (project: Project) { -> 'x } -> 'x
|
67
|
+
end
|
68
|
+
|
69
|
+
class Steep::Project::SignatureLoaded
|
70
|
+
attr_reader check: any
|
71
|
+
attr_reader loaded_at: Time
|
72
|
+
attr_reader file_paths: Array<Pathname>
|
73
|
+
|
74
|
+
def initialize: (check: any, loaded_at: Time, file_paths: Array<Pathname>) -> any
|
75
|
+
end
|
76
|
+
|
77
|
+
class Steep::Project::SignatureHasSyntaxError
|
78
|
+
attr_reader errors: Hash<Pathname, any>
|
79
|
+
def initialize: (errors: Hash<Pathname, any>) -> any
|
80
|
+
end
|
81
|
+
|
82
|
+
class Steep::Project::SignatureHasError
|
83
|
+
attr_reader errors: Array<any>
|
84
|
+
def initialize: (errors: Array<any>) -> any
|
85
|
+
end
|
86
|
+
|
87
|
+
class Steep::Project
|
88
|
+
attr_reader listener: _Listener
|
89
|
+
attr_reader source_files: Hash<Pathname, SourceFile>
|
90
|
+
attr_reader signature_files: Hash<Pathname, SignatureFile>
|
91
|
+
|
92
|
+
attr_reader signature: (SignatureLoaded | SignatureHasError | SignatureHasSyntaxError | nil)
|
93
|
+
|
94
|
+
def initialize: (?_Listener?) -> any
|
95
|
+
def clear: -> void
|
96
|
+
def type_check: (?force_signatures: bool, ?force_sources: bool) -> void
|
97
|
+
|
98
|
+
def success?: -> bool
|
99
|
+
def has_type_error?: -> bool
|
100
|
+
def errors: -> Array<type_error>
|
101
|
+
def each_updated_source: (?force: bool) { (SourceFile) -> void } -> void
|
102
|
+
| (?force: bool) -> Enumerator<SourceFile, void>
|
103
|
+
def signature_updated?: -> bool
|
104
|
+
def reload_signature: -> void
|
105
|
+
def validate_signature: (any) -> Array<any>
|
106
|
+
end
|
data/smoke/hash/f.rb
ADDED
data/stdlib/builtin.rbi
CHANGED
@@ -240,6 +240,9 @@ class Hash<'key, 'value>
|
|
240
240
|
def key?: ('key) -> bool
|
241
241
|
def merge: (Hash<'key, 'value>) -> Hash<'key, 'value>
|
242
242
|
def delete: ('key) -> 'value?
|
243
|
+
def each_value: { ('value) -> void } -> self
|
244
|
+
| -> Enumerator<'valud, self>
|
245
|
+
def empty?: -> bool
|
243
246
|
|
244
247
|
include Enumerable<['key, 'value], self>
|
245
248
|
end
|
data/steep.gemspec
CHANGED
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
|
25
25
|
spec.required_ruby_version = '>= 2.5.0'
|
26
26
|
|
27
|
-
spec.add_development_dependency "bundler", "
|
27
|
+
spec.add_development_dependency "bundler", ">= 1.13"
|
28
28
|
spec.add_development_dependency "rake", "~> 10.0"
|
29
29
|
spec.add_development_dependency "minitest", "~> 5.0"
|
30
30
|
spec.add_development_dependency "racc", "~> 1.4"
|
@@ -33,4 +33,6 @@ Gem::Specification.new do |spec|
|
|
33
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
|
+
spec.add_runtime_dependency "listen", "~> 3.1"
|
37
|
+
spec.add_runtime_dependency "pry", "~> 0.12.2"
|
36
38
|
end
|
metadata
CHANGED
@@ -1,27 +1,27 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: steep
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.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:
|
11
|
+
date: 2019-03-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.13'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.13'
|
27
27
|
- !ruby/object:Gem::Dependency
|
@@ -128,6 +128,34 @@ dependencies:
|
|
128
128
|
- - "<"
|
129
129
|
- !ruby/object:Gem::Version
|
130
130
|
version: '4.0'
|
131
|
+
- !ruby/object:Gem::Dependency
|
132
|
+
name: listen
|
133
|
+
requirement: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - "~>"
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '3.1'
|
138
|
+
type: :runtime
|
139
|
+
prerelease: false
|
140
|
+
version_requirements: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - "~>"
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '3.1'
|
145
|
+
- !ruby/object:Gem::Dependency
|
146
|
+
name: pry
|
147
|
+
requirement: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - "~>"
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: 0.12.2
|
152
|
+
type: :runtime
|
153
|
+
prerelease: false
|
154
|
+
version_requirements: !ruby/object:Gem::Requirement
|
155
|
+
requirements:
|
156
|
+
- - "~>"
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: 0.12.2
|
131
159
|
description: Gradual Typing for Ruby
|
132
160
|
email:
|
133
161
|
- matsumoto@soutaro.com
|
@@ -189,8 +217,8 @@ files:
|
|
189
217
|
- lib/steep/drivers/print_interface.rb
|
190
218
|
- lib/steep/drivers/scaffold.rb
|
191
219
|
- lib/steep/drivers/utils/each_signature.rb
|
192
|
-
- lib/steep/drivers/utils/validator.rb
|
193
220
|
- lib/steep/drivers/validate.rb
|
221
|
+
- lib/steep/drivers/watch.rb
|
194
222
|
- lib/steep/errors.rb
|
195
223
|
- lib/steep/interface/abstract.rb
|
196
224
|
- lib/steep/interface/builder.rb
|
@@ -202,6 +230,10 @@ files:
|
|
202
230
|
- lib/steep/names.rb
|
203
231
|
- lib/steep/parser.rb
|
204
232
|
- lib/steep/parser.y
|
233
|
+
- lib/steep/project.rb
|
234
|
+
- lib/steep/project/file.rb
|
235
|
+
- lib/steep/project/listener.rb
|
236
|
+
- lib/steep/project/options.rb
|
205
237
|
- lib/steep/signature/errors.rb
|
206
238
|
- lib/steep/source.rb
|
207
239
|
- lib/steep/subtyping/check.rb
|
@@ -220,8 +252,7 @@ files:
|
|
220
252
|
- lib/steep/typing.rb
|
221
253
|
- lib/steep/version.rb
|
222
254
|
- manual/annotations.md
|
223
|
-
- sig/
|
224
|
-
- sig/types.rbi
|
255
|
+
- sig/project.rbi
|
225
256
|
- smoke/alias/a.rb
|
226
257
|
- smoke/alias/a.rbi
|
227
258
|
- smoke/alias/b.rb
|
@@ -268,6 +299,7 @@ files:
|
|
268
299
|
- smoke/hash/d.rb
|
269
300
|
- smoke/hash/e.rb
|
270
301
|
- smoke/hash/e.rbi
|
302
|
+
- smoke/hash/f.rb
|
271
303
|
- smoke/hello/hello.rb
|
272
304
|
- smoke/hello/hello.rbi
|
273
305
|
- smoke/if/a.rb
|
@@ -1,110 +0,0 @@
|
|
1
|
-
module Steep
|
2
|
-
module Drivers
|
3
|
-
module Utils
|
4
|
-
class Validator
|
5
|
-
attr_reader :stdout
|
6
|
-
attr_reader :stderr
|
7
|
-
attr_reader :verbose
|
8
|
-
|
9
|
-
def initialize(stdout:, stderr:, verbose:)
|
10
|
-
@stdout = stdout
|
11
|
-
@stderr = stderr
|
12
|
-
@verbose = verbose
|
13
|
-
end
|
14
|
-
|
15
|
-
def run(env:, builder:, check:)
|
16
|
-
result = true
|
17
|
-
|
18
|
-
env.each do |sig|
|
19
|
-
yield sig if block_given?
|
20
|
-
|
21
|
-
case sig
|
22
|
-
when AST::Signature::Interface
|
23
|
-
yield_self do
|
24
|
-
instance_interface = builder.build_interface(sig.name)
|
25
|
-
|
26
|
-
args = instance_interface.params.map {|var| AST::Types::Var.fresh(var) }
|
27
|
-
instance_type = AST::Types::Name::Interface.new(name: sig.name, args: args)
|
28
|
-
|
29
|
-
instance_interface.instantiate(type: instance_type,
|
30
|
-
args: args,
|
31
|
-
instance_type: instance_type,
|
32
|
-
module_type: nil).validate(check)
|
33
|
-
end
|
34
|
-
|
35
|
-
when AST::Signature::Module
|
36
|
-
yield_self do
|
37
|
-
instance_interface = builder.build_instance(sig.name)
|
38
|
-
instance_args = instance_interface.params.map {|var| AST::Types::Var.fresh(var) }
|
39
|
-
|
40
|
-
module_interface = builder.build_module(sig.name)
|
41
|
-
module_args = module_interface.params.map {|var| AST::Types::Var.fresh(var) }
|
42
|
-
|
43
|
-
instance_type = AST::Types::Name::Instance.new(name: sig.name, args: instance_args)
|
44
|
-
module_type = AST::Types::Name::Module.new(name: sig.name)
|
45
|
-
|
46
|
-
stdout.puts "👀 Validating instance methods..." if verbose
|
47
|
-
instance_interface.instantiate(type: instance_type,
|
48
|
-
args: instance_args,
|
49
|
-
instance_type: instance_type,
|
50
|
-
module_type: module_type).validate(check)
|
51
|
-
|
52
|
-
stdout.puts "👀 Validating class methods..." if verbose
|
53
|
-
module_interface.instantiate(type: module_type,
|
54
|
-
args: module_args,
|
55
|
-
instance_type: instance_type,
|
56
|
-
module_type: module_type).validate(check)
|
57
|
-
end
|
58
|
-
|
59
|
-
when AST::Signature::Class
|
60
|
-
yield_self do
|
61
|
-
instance_interface = builder.build_instance(sig.name)
|
62
|
-
instance_args = instance_interface.params.map {|var| AST::Types::Var.fresh(var) }
|
63
|
-
|
64
|
-
module_interface = builder.build_class(sig.name, constructor: true)
|
65
|
-
module_args = module_interface.params.map {|var| AST::Types::Var.fresh(var) }
|
66
|
-
|
67
|
-
instance_type = AST::Types::Name::Instance.new(name: sig.name, args: instance_args)
|
68
|
-
module_type = AST::Types::Name::Class.new(name: sig.name, constructor: true)
|
69
|
-
|
70
|
-
stdout.puts "👀 Validating instance methods..." if verbose
|
71
|
-
instance_interface.instantiate(type: instance_type,
|
72
|
-
args: instance_args,
|
73
|
-
instance_type: instance_type,
|
74
|
-
module_type: module_type).validate(check)
|
75
|
-
|
76
|
-
stdout.puts "👀 Validating class methods..." if verbose
|
77
|
-
module_interface.instantiate(type: module_type,
|
78
|
-
args: module_args,
|
79
|
-
instance_type: instance_type,
|
80
|
-
module_type: module_type).validate(check)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
rescue Interface::Instantiated::InvalidMethodOverrideError => exn
|
85
|
-
result = false
|
86
|
-
stdout.puts "😱 #{exn.message}"
|
87
|
-
exn.result.trace.each do |s, t|
|
88
|
-
case s
|
89
|
-
when Interface::Method
|
90
|
-
stdout.puts " #{s.name}(#{s.type_name}) <: #{t.name}(#{t.type_name})"
|
91
|
-
when Interface::MethodType
|
92
|
-
stdout.puts " #{s} <: #{t} (#{s.location&.name||"?"}:#{s.location&.start_line||"?"})"
|
93
|
-
else
|
94
|
-
stdout.puts " #{s} <: #{t}"
|
95
|
-
end
|
96
|
-
end
|
97
|
-
stdout.puts " 🚨 #{exn.result.error.message}"
|
98
|
-
|
99
|
-
rescue Interface::Instantiated::InvalidIvarOverrideError => exn
|
100
|
-
result = false
|
101
|
-
stdout.puts "😱 #{exn.message}"
|
102
|
-
|
103
|
-
end
|
104
|
-
|
105
|
-
result
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|