steep 0.9.0 → 0.10.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 +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
|