steep 1.9.0.dev.1 → 1.9.0.dev.2
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/Steepfile +35 -12
- data/bin/rbs-inline +19 -0
- data/lib/steep/cli.rb +1 -10
- data/lib/steep/diagnostic/ruby.rb +10 -0
- data/lib/steep/drivers/check.rb +5 -9
- data/lib/steep/drivers/utils/driver_helper.rb +34 -3
- data/lib/steep/project/pattern.rb +4 -0
- data/lib/steep/server/custom_methods.rb +16 -0
- data/lib/steep/server/master.rb +36 -1
- data/lib/steep/server/type_check_controller.rb +44 -0
- data/lib/steep/type_construction.rb +11 -2
- data/lib/steep/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 89c207623c288c2142cdcf7d7de7f404da4d160b5bc40c84210116a721ec4029
|
4
|
+
data.tar.gz: dfd95e726115676f4d293d312bd1f06afa6ea89336911e9887c8e4b5ee1167ff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c9800ef17d4108ff391642510701e12a0ec4e63035c74765ed1203fa9b62d964be10441d60890ab3c643dc8d0295dd2a68be5285126307f3cb401f517eaa799f
|
7
|
+
data.tar.gz: 3ef2c5d7bac4dd2d492df8e5c60322de6c06d9c33cec21e2a97e4608f235e41729f0383e0817cfd324213853cad4c34308b14f5a582eedda71d36828545d6840
|
data/Steepfile
CHANGED
@@ -1,28 +1,51 @@
|
|
1
1
|
D = Steep::Diagnostic
|
2
2
|
|
3
|
+
FileUtils.mkpath("tmp")
|
4
|
+
tmp_rbs_dir = Pathname("tmp/rbs-sig")
|
5
|
+
|
6
|
+
definition = Bundler::Definition.build(Pathname("Gemfile"), Pathname("Gemfile.lock"), nil)
|
7
|
+
rbs_dep = definition.dependencies.find {|dep| dep.name == "rbs" }
|
8
|
+
if (source = rbs_dep&.source).is_a?(Bundler::Source::Path)
|
9
|
+
unless tmp_rbs_dir.directory?
|
10
|
+
FileUtils.ln_s(Pathname.pwd + source.path + "sig", tmp_rbs_dir.to_s, force: true)
|
11
|
+
end
|
12
|
+
else
|
13
|
+
FileUtils.rm_f(tmp_rbs_dir)
|
14
|
+
library "rbs"
|
15
|
+
end
|
16
|
+
|
3
17
|
target :app do
|
18
|
+
collection_config "rbs_collection.steep.yaml"
|
19
|
+
|
4
20
|
check "lib"
|
5
21
|
ignore "lib/steep/shims"
|
6
22
|
|
7
23
|
signature "sig"
|
8
|
-
|
9
|
-
collection_config "rbs_collection.steep.yaml"
|
24
|
+
ignore_signature "sig/test"
|
10
25
|
|
11
26
|
configure_code_diagnostics(D::Ruby.strict) do |hash|
|
12
27
|
end
|
13
28
|
|
14
|
-
|
15
|
-
|
29
|
+
if tmp_rbs_dir.directory?
|
30
|
+
signature tmp_rbs_dir.to_s
|
31
|
+
else
|
32
|
+
library "rbs"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
target :test do
|
37
|
+
collection_config "rbs_collection.steep.yaml"
|
38
|
+
|
39
|
+
unreferenced!
|
40
|
+
|
41
|
+
check "test"
|
42
|
+
signature "sig/test"
|
43
|
+
|
44
|
+
configure_code_diagnostics(D::Ruby.lenient)
|
16
45
|
|
17
|
-
|
18
|
-
|
19
|
-
if (source = rbs_dep&.source).is_a?(Bundler::Source::Path)
|
20
|
-
unless Pathname(tmp_rbs_dir).exist?
|
21
|
-
FileUtils.ln_s(Pathname.pwd + source.path + "sig", tmp_rbs_dir, force: true)
|
22
|
-
end
|
23
|
-
signature tmp_rbs_dir
|
46
|
+
if tmp_rbs_dir.directory?
|
47
|
+
signature tmp_rbs_dir.to_s
|
24
48
|
else
|
25
|
-
FileUtils.rm_f(tmp_rbs_dir)
|
26
49
|
library "rbs"
|
27
50
|
end
|
28
51
|
end
|
data/bin/rbs-inline
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
BINSTUB_DIR=$(cd $(dirname $0); pwd)
|
4
|
+
GEMFILE=$(readlink -f ${BINSTUB_DIR}/../gemfile_steep/Gemfile)
|
5
|
+
ROOT_DIR=$(readlink -f ${BINSTUB_DIR}/..)
|
6
|
+
|
7
|
+
RBSINLINE="bundle exec --gemfile=${GEMFILE} rbs-inline"
|
8
|
+
|
9
|
+
if type "rbenv" > /dev/null 2>&1; then
|
10
|
+
RBSINLINE="rbenv exec ${RBSINLINE}"
|
11
|
+
else
|
12
|
+
if type "rvm" > /dev/null 2>&1; then
|
13
|
+
if [ -e ${ROOT_DIR}/.ruby-version ]; then
|
14
|
+
RBS="rvm ${ROOT_DIR} do ${RBSINLINE}"
|
15
|
+
fi
|
16
|
+
fi
|
17
|
+
fi
|
18
|
+
|
19
|
+
exec $RBSINLINE $@
|
data/lib/steep/cli.rb
CHANGED
@@ -138,31 +138,22 @@ module Steep
|
|
138
138
|
command.type_check_code = v ? true : false
|
139
139
|
end
|
140
140
|
|
141
|
-
opts.on("--validate=OPTION", ["skip", "group", "
|
141
|
+
opts.on("--validate=OPTION", ["skip", "group", "project", "library"], "Validation levels of signatures (default: group, options: skip,group,project,library)") do |level|
|
142
142
|
case level
|
143
143
|
when "skip"
|
144
144
|
command.validate_group_signatures = false
|
145
|
-
command.validate_target_signatures = false
|
146
145
|
command.validate_project_signatures = false
|
147
146
|
command.validate_library_signatures = false
|
148
147
|
when "group"
|
149
148
|
command.validate_group_signatures = true
|
150
|
-
command.validate_target_signatures = false
|
151
|
-
command.validate_project_signatures = false
|
152
|
-
command.validate_library_signatures = false
|
153
|
-
when "target"
|
154
|
-
command.validate_group_signatures = true
|
155
|
-
command.validate_target_signatures = true
|
156
149
|
command.validate_project_signatures = false
|
157
150
|
command.validate_library_signatures = false
|
158
151
|
when "project"
|
159
152
|
command.validate_group_signatures = true
|
160
|
-
command.validate_target_signatures = true
|
161
153
|
command.validate_project_signatures = true
|
162
154
|
command.validate_library_signatures = false
|
163
155
|
when "library"
|
164
156
|
command.validate_group_signatures = true
|
165
|
-
command.validate_target_signatures = true
|
166
157
|
command.validate_project_signatures = true
|
167
158
|
command.validate_library_signatures = true
|
168
159
|
end
|
@@ -917,6 +917,13 @@ module Steep
|
|
917
917
|
end
|
918
918
|
end
|
919
919
|
|
920
|
+
class UnannotatedEmptyCollection < Base
|
921
|
+
def header_line
|
922
|
+
node or raise
|
923
|
+
"Empty #{node.type} doesn't have type annotation"
|
924
|
+
end
|
925
|
+
end
|
926
|
+
|
920
927
|
ALL = ObjectSpace.each_object(Class).with_object([]) do |klass, array|
|
921
928
|
if klass < Base
|
922
929
|
array << klass
|
@@ -963,6 +970,7 @@ module Steep
|
|
963
970
|
SetterReturnTypeMismatch => :information,
|
964
971
|
SyntaxError => :hint,
|
965
972
|
TypeArgumentMismatchError => :hint,
|
973
|
+
UnannotatedEmptyCollection => :warning,
|
966
974
|
UnexpectedBlockGiven => :warning,
|
967
975
|
UnexpectedDynamicMethod => :hint,
|
968
976
|
UnexpectedError => :hint,
|
@@ -1019,6 +1027,7 @@ module Steep
|
|
1019
1027
|
SetterReturnTypeMismatch => :error,
|
1020
1028
|
SyntaxError => :hint,
|
1021
1029
|
TypeArgumentMismatchError => :error,
|
1030
|
+
UnannotatedEmptyCollection => :error,
|
1022
1031
|
UnexpectedBlockGiven => :error,
|
1023
1032
|
UnexpectedDynamicMethod => :information,
|
1024
1033
|
UnexpectedError => :information,
|
@@ -1075,6 +1084,7 @@ module Steep
|
|
1075
1084
|
SetterReturnTypeMismatch => nil,
|
1076
1085
|
SyntaxError => :hint,
|
1077
1086
|
TypeArgumentMismatchError => nil,
|
1087
|
+
UnannotatedEmptyCollection => :hint,
|
1078
1088
|
UnexpectedBlockGiven => :hint,
|
1079
1089
|
UnexpectedDynamicMethod => nil,
|
1080
1090
|
UnexpectedError => :hint,
|
data/lib/steep/drivers/check.rb
CHANGED
@@ -14,7 +14,6 @@ module Steep
|
|
14
14
|
attr_reader :active_group_names
|
15
15
|
attr_accessor :type_check_code
|
16
16
|
attr_accessor :validate_group_signatures
|
17
|
-
attr_accessor :validate_target_signatures
|
18
17
|
attr_accessor :validate_project_signatures
|
19
18
|
attr_accessor :validate_library_signatures
|
20
19
|
|
@@ -29,7 +28,6 @@ module Steep
|
|
29
28
|
@active_group_names = []
|
30
29
|
@type_check_code = true
|
31
30
|
@validate_group_signatures = true
|
32
|
-
@validate_target_signatures = false
|
33
31
|
@validate_project_signatures = false
|
34
32
|
@validate_library_signatures = false
|
35
33
|
end
|
@@ -217,19 +215,17 @@ module Steep
|
|
217
215
|
params[:signature_paths] << [target.name.to_s, target.project.absolute_path(path).to_s]
|
218
216
|
end
|
219
217
|
end
|
220
|
-
if validate_target_signatures
|
221
|
-
if group.is_a?(Project::Group)
|
222
|
-
files.each_target_signature_path(target, group) do |path|
|
223
|
-
params[:signature_paths] << [target.name.to_s, target.project.absolute_path(path).to_s]
|
224
|
-
end
|
225
|
-
end
|
226
|
-
end
|
227
218
|
if validate_project_signatures
|
228
219
|
files.each_project_signature_path(target) do |path|
|
229
220
|
if path_target = files.signature_path_target(path)
|
230
221
|
params[:signature_paths] << [path_target.name.to_s, target.project.absolute_path(path).to_s]
|
231
222
|
end
|
232
223
|
end
|
224
|
+
if group.is_a?(Project::Group)
|
225
|
+
files.each_target_signature_path(target, group) do |path|
|
226
|
+
params[:signature_paths] << [target.name.to_s, target.project.absolute_path(path).to_s]
|
227
|
+
end
|
228
|
+
end
|
233
229
|
end
|
234
230
|
if validate_library_signatures
|
235
231
|
files.each_library_path(target) do |path|
|
@@ -3,6 +3,7 @@ module Steep
|
|
3
3
|
module Utils
|
4
4
|
module DriverHelper
|
5
5
|
attr_accessor :steepfile
|
6
|
+
attr_accessor :disable_install_collection
|
6
7
|
|
7
8
|
def load_config(path: steepfile || Pathname("Steepfile"))
|
8
9
|
if path.file?
|
@@ -25,17 +26,47 @@ module Steep
|
|
25
26
|
case result = target.options.load_collection_lock
|
26
27
|
when nil, RBS::Collection::Config::Lockfile
|
27
28
|
# ok
|
28
|
-
|
29
|
+
when Pathname
|
30
|
+
# File is missing
|
29
31
|
if result == target.options.collection_config_path
|
30
|
-
|
32
|
+
# Config file is missing
|
33
|
+
Steep.ui_logger.error { "rbs-collection configuration is missing: `#{result}`" }
|
31
34
|
else
|
32
|
-
|
35
|
+
# Lockfile is missing
|
36
|
+
Steep.ui_logger.error { "Run `rbs collection install` to generate missing lockfile: `#{result}`" }
|
37
|
+
end
|
38
|
+
when YAML::SyntaxError
|
39
|
+
# File is broken
|
40
|
+
Steep.ui_logger.error { "rbs-collection setup is broken:\nsyntax error #{result.inspect}" }
|
41
|
+
when RBS::Collection::Config::CollectionNotAvailable
|
42
|
+
unless disable_install_collection
|
43
|
+
install_collection(target, target.options.collection_config_path || raise)
|
44
|
+
else
|
45
|
+
Steep.ui_logger.error { "Run `rbs collection install` to set up RBS files for gems" }
|
33
46
|
end
|
34
47
|
end
|
35
48
|
end
|
36
49
|
end
|
37
50
|
end
|
38
51
|
|
52
|
+
def install_collection(target, config_path)
|
53
|
+
Steep.ui_logger.info { "Installing RBS files for collection: #{config_path}" }
|
54
|
+
lockfile_path = RBS::Collection::Config.to_lockfile_path(config_path)
|
55
|
+
io = StringIO.new
|
56
|
+
begin
|
57
|
+
RBS::Collection::Installer.new(lockfile_path: lockfile_path, stdout: io).install_from_lockfile()
|
58
|
+
target.options.load_collection_lock(force: true)
|
59
|
+
Steep.ui_logger.debug { "Finished setting up RBS collection: " + io.string }
|
60
|
+
|
61
|
+
result = target.options.load_collection_lock(force: true)
|
62
|
+
unless result.is_a?(RBS::Collection::Config::Lockfile)
|
63
|
+
raise "Failed to set up RBS collection: #{result.inspect}"
|
64
|
+
end
|
65
|
+
rescue => exn
|
66
|
+
Steep.ui_logger.error { "Failed to set up RBS collection: #{exn.inspect}" }
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
39
70
|
def request_id
|
40
71
|
SecureRandom.alphanumeric(10)
|
41
72
|
end
|
@@ -29,6 +29,14 @@ module Steep
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
+
module TypeCheckGroups
|
33
|
+
METHOD = "$/steep/typecheck/groups"
|
34
|
+
|
35
|
+
def self.notification(params)
|
36
|
+
{ method: METHOD, params: params }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
32
40
|
module TypeCheck__Start
|
33
41
|
METHOD = "$/steep/typecheck/start"
|
34
42
|
|
@@ -56,6 +64,14 @@ module Steep
|
|
56
64
|
{ id: id, result: result }
|
57
65
|
end
|
58
66
|
end
|
67
|
+
|
68
|
+
module Groups
|
69
|
+
METHOD = "$/steep/groups"
|
70
|
+
|
71
|
+
def self.response(id, result)
|
72
|
+
{ id: id, result: result }
|
73
|
+
end
|
74
|
+
end
|
59
75
|
end
|
60
76
|
end
|
61
77
|
end
|
data/lib/steep/server/master.rb
CHANGED
@@ -382,7 +382,11 @@ module Steep
|
|
382
382
|
declaration_provider: false,
|
383
383
|
implementation_provider: true,
|
384
384
|
type_definition_provider: true
|
385
|
-
)
|
385
|
+
),
|
386
|
+
server_info: {
|
387
|
+
name: "steep",
|
388
|
+
version: VERSION
|
389
|
+
}
|
386
390
|
)
|
387
391
|
}
|
388
392
|
)
|
@@ -657,6 +661,18 @@ module Steep
|
|
657
661
|
|
658
662
|
start_type_check(request: request, last_request: nil)
|
659
663
|
|
664
|
+
when CustomMethods::TypeCheckGroups::METHOD
|
665
|
+
params = message[:params] #: CustomMethods::TypeCheckGroups::params
|
666
|
+
|
667
|
+
groups = params.fetch(:groups)
|
668
|
+
|
669
|
+
progress = work_done_progress(SecureRandom.uuid)
|
670
|
+
progress.begin("Type checking #{groups.empty? ? "project" : groups.join(", ")}", request_id: fresh_request_id)
|
671
|
+
|
672
|
+
request = controller.make_group_request(groups, progress: progress)
|
673
|
+
request.needs_response = false
|
674
|
+
start_type_check(request: request, last_request: current_type_check_request, report_progress_threshold: 0)
|
675
|
+
|
660
676
|
when "$/ping"
|
661
677
|
enqueue_write_job SendMessageJob.to_client(
|
662
678
|
message: {
|
@@ -665,6 +681,25 @@ module Steep
|
|
665
681
|
}
|
666
682
|
)
|
667
683
|
|
684
|
+
when CustomMethods::Groups::METHOD
|
685
|
+
groups = [] #: Array[String]
|
686
|
+
|
687
|
+
project.targets.each do |target|
|
688
|
+
unless target.source_pattern.empty? && target.signature_pattern.empty?
|
689
|
+
groups << target.name.to_s
|
690
|
+
end
|
691
|
+
|
692
|
+
target.groups.each do |group|
|
693
|
+
unless group.source_pattern.empty? && group.signature_pattern.empty?
|
694
|
+
groups << "#{target.name}.#{group.name}"
|
695
|
+
end
|
696
|
+
end
|
697
|
+
end
|
698
|
+
|
699
|
+
enqueue_write_job(SendMessageJob.to_client(
|
700
|
+
message: CustomMethods::Groups.response(message[:id], groups)
|
701
|
+
))
|
702
|
+
|
668
703
|
when "shutdown"
|
669
704
|
start_type_checking_queue.cancel
|
670
705
|
|
@@ -254,6 +254,50 @@ module Steep
|
|
254
254
|
end
|
255
255
|
end
|
256
256
|
|
257
|
+
def make_group_request(groups, progress:)
|
258
|
+
TypeCheckController::Request.new(guid: progress.guid, progress: progress).tap do |request|
|
259
|
+
if groups.empty?
|
260
|
+
files.signature_paths.each do |path, target_group|
|
261
|
+
target_group = target_group.target if target_group.is_a?(Project::Group)
|
262
|
+
request.signature_paths << [target_group.name, path]
|
263
|
+
end
|
264
|
+
files.source_paths.each do |path, target_group|
|
265
|
+
target_group = target_group.target if target_group.is_a?(Project::Group)
|
266
|
+
request.code_paths << [target_group.name, path]
|
267
|
+
end
|
268
|
+
else
|
269
|
+
group_set = groups.map do |group_name|
|
270
|
+
target_name, group_name = group_name.split(".", 2)
|
271
|
+
target_name or raise
|
272
|
+
|
273
|
+
target_name = target_name.to_sym
|
274
|
+
group_name = group_name.to_sym if group_name
|
275
|
+
|
276
|
+
if group_name
|
277
|
+
if target = project.targets.find {|target| target.name == target_name }
|
278
|
+
target.groups.find {|group| group.name == group_name }
|
279
|
+
end
|
280
|
+
else
|
281
|
+
project.targets.find {|target| target.name == target_name }
|
282
|
+
end
|
283
|
+
end.compact.to_set
|
284
|
+
|
285
|
+
files.signature_paths.each do |path, target_group|
|
286
|
+
if group_set.include?(target_group)
|
287
|
+
target_group = target_group.target if target_group.is_a?(Project::Group)
|
288
|
+
request.signature_paths << [target_group.name, path]
|
289
|
+
end
|
290
|
+
end
|
291
|
+
files.source_paths.each do |path, target_group|
|
292
|
+
if group_set.include?(target_group)
|
293
|
+
target_group = target_group.target if target_group.is_a?(Project::Group)
|
294
|
+
request.code_paths << [target_group.name, path]
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
257
301
|
def make_request(guid: SecureRandom.uuid, include_unchanged: false, progress:)
|
258
302
|
TypeCheckController::Request.new(guid: guid, progress: progress).tap do |request|
|
259
303
|
if include_unchanged
|
@@ -1436,7 +1436,7 @@ module Steep
|
|
1436
1436
|
# ok
|
1437
1437
|
else
|
1438
1438
|
unless hint == pair.type
|
1439
|
-
pair.constr.typing.add_error Diagnostic::Ruby::
|
1439
|
+
pair.constr.typing.add_error Diagnostic::Ruby::UnannotatedEmptyCollection.new(node: node)
|
1440
1440
|
end
|
1441
1441
|
end
|
1442
1442
|
end
|
@@ -1704,7 +1704,7 @@ module Steep
|
|
1704
1704
|
add_typing node, type: array
|
1705
1705
|
end
|
1706
1706
|
else
|
1707
|
-
typing.add_error Diagnostic::Ruby::
|
1707
|
+
typing.add_error Diagnostic::Ruby::UnannotatedEmptyCollection.new(node: node)
|
1708
1708
|
add_typing node, type: AST::Builtin::Array.instance_type(AST::Builtin.any_type)
|
1709
1709
|
end
|
1710
1710
|
else
|
@@ -4763,6 +4763,15 @@ module Steep
|
|
4763
4763
|
|
4764
4764
|
def try_tuple_type!(node, hint: nil)
|
4765
4765
|
if node.type == :array
|
4766
|
+
if node.children.size == 1 && node.children[0]&.type == :splat
|
4767
|
+
# Skip the array construct
|
4768
|
+
splat_node = node.children[0] or raise
|
4769
|
+
splat_value = splat_node.children[0] or raise
|
4770
|
+
|
4771
|
+
type, constr = try_tuple_type!(splat_value, hint: hint)
|
4772
|
+
_, constr = constr.add_typing(splat_node, type: AST::Types::Any.instance)
|
4773
|
+
return constr.add_typing(node, type: type)
|
4774
|
+
end
|
4766
4775
|
if hint.nil? || hint.is_a?(AST::Types::Tuple)
|
4767
4776
|
typing.new_child() do |child_typing|
|
4768
4777
|
if pair = with_new_typing(child_typing).try_tuple_type(node, hint)
|
data/lib/steep/version.rb
CHANGED
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: 1.9.0.dev.
|
4
|
+
version: 1.9.0.dev.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Soutaro Matsumoto
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-11-
|
11
|
+
date: 2024-11-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|
@@ -245,6 +245,7 @@ files:
|
|
245
245
|
- bin/output_rebaseline.rb
|
246
246
|
- bin/output_test.rb
|
247
247
|
- bin/rbs
|
248
|
+
- bin/rbs-inline
|
248
249
|
- bin/setup
|
249
250
|
- bin/stackprof_test.rb
|
250
251
|
- bin/steep
|
@@ -412,7 +413,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
412
413
|
- !ruby/object:Gem::Version
|
413
414
|
version: '0'
|
414
415
|
requirements: []
|
415
|
-
rubygems_version: 3.5.
|
416
|
+
rubygems_version: 3.5.11
|
416
417
|
signing_key:
|
417
418
|
specification_version: 4
|
418
419
|
summary: Gradual Typing for Ruby
|