steep 1.8.2 → 1.9.0.dev.1

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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +0 -12
  3. data/Steepfile +0 -14
  4. data/lib/steep/cli.rb +47 -5
  5. data/lib/steep/diagnostic/ruby.rb +1 -58
  6. data/lib/steep/drivers/annotations.rb +1 -1
  7. data/lib/steep/drivers/check.rb +107 -1
  8. data/lib/steep/drivers/checkfile.rb +10 -8
  9. data/lib/steep/drivers/print_project.rb +83 -40
  10. data/lib/steep/drivers/utils/driver_helper.rb +5 -3
  11. data/lib/steep/drivers/watch.rb +24 -2
  12. data/lib/steep/index/signature_symbol_provider.rb +8 -8
  13. data/lib/steep/interface/builder.rb +14 -1
  14. data/lib/steep/interface/function.rb +2 -2
  15. data/lib/steep/path_helper.rb +4 -2
  16. data/lib/steep/project/dsl.rb +176 -151
  17. data/lib/steep/project/group.rb +31 -0
  18. data/lib/steep/project/target.rb +32 -6
  19. data/lib/steep/project.rb +38 -10
  20. data/lib/steep/server/delay_queue.rb +0 -3
  21. data/lib/steep/server/interaction_worker.rb +2 -11
  22. data/lib/steep/server/master.rb +95 -281
  23. data/lib/steep/server/target_group_files.rb +205 -0
  24. data/lib/steep/server/type_check_controller.rb +322 -0
  25. data/lib/steep/server/type_check_worker.rb +60 -86
  26. data/lib/steep/services/file_loader.rb +23 -0
  27. data/lib/steep/services/goto_service.rb +40 -31
  28. data/lib/steep/services/hover_provider/singleton_methods.rb +4 -4
  29. data/lib/steep/services/path_assignment.rb +23 -4
  30. data/lib/steep/services/type_check_service.rb +76 -159
  31. data/lib/steep/signature/validator.rb +4 -4
  32. data/lib/steep/subtyping/check.rb +2 -2
  33. data/lib/steep/thread_waiter.rb +24 -16
  34. data/lib/steep/type_construction.rb +5 -5
  35. data/lib/steep/type_inference/block_params.rb +1 -2
  36. data/lib/steep/type_inference/context.rb +1 -1
  37. data/lib/steep/type_inference/type_env.rb +4 -4
  38. data/lib/steep/type_inference/type_env_builder.rb +1 -1
  39. data/lib/steep/version.rb +1 -1
  40. data/lib/steep.rb +6 -4
  41. data/sample/Steepfile +6 -0
  42. data/sample/lib/conference.rb +1 -5
  43. data/steep.gemspec +7 -1
  44. metadata +8 -6
  45. data/lib/steep/drivers/validate.rb +0 -65
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6f40f4acb0e71a6cfd2b751297f2fc1a9cd18a87545d24cec51c0da5f1e9792e
4
- data.tar.gz: 947ea73b078a7c1b9dc37e2855a6e483d1bbc919414b97226a3393bf92cb6bf8
3
+ metadata.gz: 37bf13501b4d8d6e4b6fa5b0702e0a978a6488e674832e36168070788c1b3367
4
+ data.tar.gz: 6184ef95ab4f594841ee4d7ef775a68df571bb21b981beff18e0a7cddd53ae7e
5
5
  SHA512:
6
- metadata.gz: b146bd6a93a59b5ec7a3029b061fc352c1e93c9bd87cfac89783b9a54175f076bc208a6f94adc32fa2a1802fdc94a422f1c64fbca555eb5ad93481ce7ff88b5d
7
- data.tar.gz: d746bee9df6ab60f43811ec81a415348927bde046cba2cf7b2dd5e4204438e9dc317456ed9d61358fbbfe22125c569451687b9d528b17d1792e470e29dac43c1
6
+ metadata.gz: b1d51f5e77be8d2ea4ddb45982e2e4515afcb16453784feef442ec618ea9584bf75a52f12654ef63283367dc1d5a3cd5e10be71cd3e02f9cde71566402f86ed0
7
+ data.tar.gz: 92e5a0e27efbf0cfc629ed7fbce8576e8a8657c6abd5abc8b11f4e51c7087d2ca2d36c6ba7415ce9d1d53ea994e42068a857cbabb7a64940ec476321346a2829
data/CHANGELOG.md CHANGED
@@ -1,17 +1,5 @@
1
1
  # CHANGELOG
2
2
 
3
- ## 1.8.2 (2024-10-24)
4
-
5
- ### Language server
6
-
7
- * Ignore `didChangeWatchedFiles notification` for open files ([#1290](https://github.com/soutaro/steep/pull/1290))
8
-
9
- ## 1.8.1 (2024-10-08)
10
-
11
- ### Language server
12
-
13
- * Skip sending response to `$/steep/typecheck` request from `steep langserver` ([#1268](https://github.com/soutaro/steep/pull/1268), backport [#1267](https://github.com/soutaro/steep/pull/1267))
14
-
15
3
  ## 1.8.0 (2024-09-30)
16
4
 
17
5
  ### Type checker core
data/Steepfile CHANGED
@@ -25,18 +25,4 @@ target :app do
25
25
  FileUtils.rm_f(tmp_rbs_dir)
26
26
  library "rbs"
27
27
  end
28
-
29
- library(
30
- "rdoc",
31
- "monitor",
32
- "tsort",
33
- "uri",
34
- 'yaml',
35
- 'pstore',
36
- 'singleton',
37
- 'shellwords',
38
- 'find',
39
- 'digest',
40
- "optparse",
41
- )
42
28
  end
data/lib/steep/cli.rb CHANGED
@@ -126,6 +126,48 @@ module Steep
126
126
  opts.on("--severity-level=LEVEL", /^error|warning|information|hint$/, "Specify the minimum diagnostic severity to be recognized as an error (defaults: warning): error, warning, information, or hint") do |level|
127
127
  command.severity_level = level.to_sym
128
128
  end
129
+
130
+ opts.on("--group=GROUP", "Specify target/group name to type check") do |arg|
131
+ # @type var group: String
132
+ target, group = arg.split(".")
133
+ target or raise
134
+ command.active_group_names << [target.to_sym, group&.to_sym]
135
+ end
136
+
137
+ opts.on("--[no-]type-check", "Type check Ruby code") do |v|
138
+ command.type_check_code = v ? true : false
139
+ end
140
+
141
+ opts.on("--validate=OPTION", ["skip", "group", "target", "project", "library"], "Validation levels of signatures (default: group, options: skip,group,target,project,library)") do |level|
142
+ case level
143
+ when "skip"
144
+ command.validate_group_signatures = false
145
+ command.validate_target_signatures = false
146
+ command.validate_project_signatures = false
147
+ command.validate_library_signatures = false
148
+ when "group"
149
+ 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
+ command.validate_project_signatures = false
157
+ command.validate_library_signatures = false
158
+ when "project"
159
+ command.validate_group_signatures = true
160
+ command.validate_target_signatures = true
161
+ command.validate_project_signatures = true
162
+ command.validate_library_signatures = false
163
+ when "library"
164
+ command.validate_group_signatures = true
165
+ command.validate_target_signatures = true
166
+ command.validate_project_signatures = true
167
+ command.validate_library_signatures = true
168
+ end
169
+ end
170
+
129
171
  handle_jobs_option command.jobs_option, opts
130
172
  handle_logging_options opts
131
173
  end.parse!(argv)
@@ -179,11 +221,8 @@ module Steep
179
221
  end
180
222
 
181
223
  def process_validate
182
- Drivers::Validate.new(stdout: stdout, stderr: stderr).tap do |command|
183
- OptionParser.new do |opts|
184
- handle_logging_options opts
185
- end.parse!(argv)
186
- end.run
224
+ stderr.puts "`steep validate` is deprecated. Use `steep check` with `--validate` option instead."
225
+ 1
187
226
  end
188
227
 
189
228
  def process_annotations
@@ -202,6 +241,9 @@ module Steep
202
241
  OptionParser.new do |opts|
203
242
  opts.banner = "Usage: steep project [options]"
204
243
  opts.on("--steepfile=PATH") {|path| command.steepfile = Pathname(path) }
244
+ opts.on("--[no-]print-files", "Print files") {|v|
245
+ command.print_files = v ? true : false
246
+ }
205
247
  handle_logging_options opts
206
248
  end.parse!(argv)
207
249
  end.run
@@ -458,22 +458,6 @@ module Steep
458
458
  end
459
459
  end
460
460
 
461
- class IncompatibleMethodTypeAnnotation < Base
462
- attr_reader :interface_method
463
- attr_reader :annotation_method
464
- attr_reader :result
465
-
466
- include ResultPrinter
467
-
468
- def initialize(node:, interface_method:, annotation_method:, result:)
469
- raise
470
- super(node: node)
471
- @interface_method = interface_method
472
- @annotation_method = annotation_method
473
- @result = result
474
- end
475
- end
476
-
477
461
  class MethodReturnTypeAnnotationMismatch < Base
478
462
  attr_reader :method_type
479
463
  attr_reader :annotation_type
@@ -697,25 +681,6 @@ module Steep
697
681
  end
698
682
  end
699
683
 
700
- class IncompatibleTypeCase < Base
701
- attr_reader :var_name
702
- attr_reader :result
703
- attr_reader :relation
704
-
705
- def initialize(node:, var_name:, result:, relation:)
706
- super(node: node)
707
- @var_name = var_name
708
- @result = result
709
- @relation = relation
710
- end
711
-
712
- include ResultPrinter
713
-
714
- def header_line
715
- "Type annotation for branch about `#{var_name}` is incompatible since #{relation} doesn't hold"
716
- end
717
- end
718
-
719
684
  class UnreachableBranch < Base
720
685
  def header_line
721
686
  "The branch is unreachable"
@@ -735,19 +700,6 @@ module Steep
735
700
  end
736
701
  end
737
702
 
738
- class UnexpectedSplat < Base
739
- attr_reader :type
740
-
741
- def initialize(node:, type:)
742
- super(node: node)
743
- @type = type
744
- end
745
-
746
- def header_line
747
- "Hash splat is given with object other than `Hash[X, Y]`"
748
- end
749
- end
750
-
751
703
  class ProcTypeExpected < Base
752
704
  attr_reader :type
753
705
 
@@ -991,8 +943,6 @@ module Steep
991
943
  IncompatibleAnnotation => :hint,
992
944
  IncompatibleArgumentForwarding => :warning,
993
945
  IncompatibleAssignment => :hint,
994
- IncompatibleMethodTypeAnnotation => :hint,
995
- IncompatibleTypeCase => :hint,
996
946
  InsufficientKeywordArguments => :error,
997
947
  InsufficientPositionalArguments => :error,
998
948
  InsufficientTypeArgument => :hint,
@@ -1020,7 +970,6 @@ module Steep
1020
970
  UnexpectedJumpValue => :hint,
1021
971
  UnexpectedKeywordArgument => :error,
1022
972
  UnexpectedPositionalArgument => :error,
1023
- UnexpectedSplat => :hint,
1024
973
  UnexpectedSuper => :information,
1025
974
  UnexpectedTypeArgument => :hint,
1026
975
  UnexpectedYield => :warning,
@@ -1050,8 +999,6 @@ module Steep
1050
999
  IncompatibleAnnotation => :error,
1051
1000
  IncompatibleArgumentForwarding => :error,
1052
1001
  IncompatibleAssignment => :error,
1053
- IncompatibleMethodTypeAnnotation => :error,
1054
- IncompatibleTypeCase => :error,
1055
1002
  InsufficientKeywordArguments => :error,
1056
1003
  InsufficientPositionalArguments => :error,
1057
1004
  InsufficientTypeArgument => :error,
@@ -1079,7 +1026,6 @@ module Steep
1079
1026
  UnexpectedJumpValue => :error,
1080
1027
  UnexpectedKeywordArgument => :error,
1081
1028
  UnexpectedPositionalArgument => :error,
1082
- UnexpectedSplat => :warning,
1083
1029
  UnexpectedSuper => :error,
1084
1030
  UnexpectedTypeArgument => :error,
1085
1031
  UnexpectedYield => :error,
@@ -1109,8 +1055,6 @@ module Steep
1109
1055
  IncompatibleAnnotation => nil,
1110
1056
  IncompatibleArgumentForwarding => :information,
1111
1057
  IncompatibleAssignment => :hint,
1112
- IncompatibleMethodTypeAnnotation => nil,
1113
- IncompatibleTypeCase => nil,
1114
1058
  InsufficientKeywordArguments => :information,
1115
1059
  InsufficientPositionalArguments => :information,
1116
1060
  InsufficientTypeArgument => nil,
@@ -1138,7 +1082,6 @@ module Steep
1138
1082
  UnexpectedJumpValue => nil,
1139
1083
  UnexpectedKeywordArgument => :information,
1140
1084
  UnexpectedPositionalArgument => :information,
1141
- UnexpectedSplat => nil,
1142
1085
  UnexpectedSuper => nil,
1143
1086
  UnexpectedTypeArgument => nil,
1144
1087
  UnexpectedYield => :information,
@@ -1155,7 +1098,7 @@ module Steep
1155
1098
  end
1156
1099
 
1157
1100
  def self.silent
1158
- @silent ||= ALL.each.with_object({}) do |klass, hash|
1101
+ @silent ||= ALL.each.with_object({}) do |klass, hash| #$ template
1159
1102
  hash[klass] = nil
1160
1103
  end.freeze
1161
1104
  end
@@ -21,7 +21,7 @@ module Steep
21
21
 
22
22
  project.targets.each do |target|
23
23
  Steep.logger.tagged "target=#{target.name}" do
24
- service = Services::SignatureService.load_from(target.new_env_loader(project: project))
24
+ service = Services::SignatureService.load_from(target.new_env_loader())
25
25
 
26
26
  sigs = loader.load_changes(target.signature_pattern, changes: {})
27
27
  service.update(sigs)
@@ -10,6 +10,13 @@ module Steep
10
10
  attr_accessor :save_expectations_path
11
11
  attr_accessor :severity_level
12
12
  attr_reader :jobs_option
13
+ attr_reader :targets
14
+ attr_reader :active_group_names
15
+ attr_accessor :type_check_code
16
+ attr_accessor :validate_group_signatures
17
+ attr_accessor :validate_target_signatures
18
+ attr_accessor :validate_project_signatures
19
+ attr_accessor :validate_library_signatures
13
20
 
14
21
  include Utils::DriverHelper
15
22
 
@@ -19,6 +26,28 @@ module Steep
19
26
  @command_line_patterns = []
20
27
  @severity_level = :warning
21
28
  @jobs_option = Utils::JobsOption.new()
29
+ @active_group_names = []
30
+ @type_check_code = true
31
+ @validate_group_signatures = true
32
+ @validate_target_signatures = false
33
+ @validate_project_signatures = false
34
+ @validate_library_signatures = false
35
+ end
36
+
37
+ def active_group?(group)
38
+ return true if active_group_names.empty?
39
+
40
+ case group
41
+ when Project::Target
42
+ active_group_names.any? {|target_name, group_name|
43
+ target_name == group.name && group_name == nil
44
+ }
45
+ when Project::Group
46
+ active_group_names.any? {|target_name, group_name|
47
+ target_name == group.target.name &&
48
+ (group_name == group.name || group_name.nil?)
49
+ }
50
+ end
22
51
  end
23
52
 
24
53
  def run
@@ -64,9 +93,54 @@ module Steep
64
93
  client_writer.write({ method: :initialize, id: initialize_id, params: DEFAULT_CLI_LSP_INITIALIZE_PARAMS })
65
94
  wait_for_response_id(reader: client_reader, id: initialize_id)
66
95
 
96
+ params = { library_paths: [], signature_paths: [], code_paths: [] } #: Server::CustomMethods::TypeCheck::params
97
+
98
+ if command_line_patterns.empty?
99
+ files = Server::TargetGroupFiles.new(project)
100
+ loader = Services::FileLoader.new(base_dir: project.base_dir)
101
+
102
+ project.targets.each do |target|
103
+ target.new_env_loader.each_dir do |_, dir|
104
+ RBS::FileFinder.each_file(dir, skip_hidden: true) do |path|
105
+ files.add_library_path(target, path)
106
+ end
107
+ end
108
+
109
+ loader.each_path_in_target(target) do |path|
110
+ files.add_path(path)
111
+ end
112
+ end
113
+
114
+ project.targets.each do |target|
115
+ target.groups.each do |group|
116
+ if active_group?(group)
117
+ load_files(files, group.target, group, params: params)
118
+ end
119
+ end
120
+ if active_group?(target)
121
+ load_files(files, target, target, params: params)
122
+ end
123
+ end
124
+ else
125
+ command_line_patterns.each do |pattern|
126
+ path = Pathname(pattern)
127
+ path = project.absolute_path(path)
128
+ next unless path.file?
129
+ if target = project.target_for_source_path(path)
130
+ params[:code_paths] << [target.name.to_s, path.to_s]
131
+ end
132
+ if target = project.target_for_signature_path(path)
133
+ params[:signature_paths] << [target.name.to_s, path.to_s]
134
+ end
135
+ end
136
+ end
137
+
138
+ Steep.logger.info { "Starting type check with #{params[:code_paths].size} Ruby files and #{params[:signature_paths].size} RBS signatures..." }
139
+ Steep.logger.debug { params.inspect }
140
+
67
141
  request_guid = SecureRandom.uuid
68
142
  Steep.logger.info { "Starting type checking: #{request_guid}" }
69
- client_writer.write(Server::CustomMethods::TypeCheck.request(request_guid, { guid: request_guid}))
143
+ client_writer.write(Server::CustomMethods::TypeCheck.request(request_guid, params))
70
144
 
71
145
  diagnostic_notifications = [] #: Array[LanguageServer::Protocol::Interface::PublishDiagnosticsParams]
72
146
  error_messages = [] #: Array[String]
@@ -132,6 +206,38 @@ module Steep
132
206
  return 1
133
207
  end
134
208
 
209
+ def load_files(files, target, group, params:)
210
+ if type_check_code
211
+ files.each_group_source_path(group) do |path|
212
+ params[:code_paths] << [target.name.to_s, target.project.absolute_path(path).to_s]
213
+ end
214
+ end
215
+ if validate_group_signatures
216
+ files.each_group_signature_path(group) do |path|
217
+ params[:signature_paths] << [target.name.to_s, target.project.absolute_path(path).to_s]
218
+ end
219
+ 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
+ if validate_project_signatures
228
+ files.each_project_signature_path(target) do |path|
229
+ if path_target = files.signature_path_target(path)
230
+ params[:signature_paths] << [path_target.name.to_s, target.project.absolute_path(path).to_s]
231
+ end
232
+ end
233
+ end
234
+ if validate_library_signatures
235
+ files.each_library_path(target) do |path|
236
+ params[:library_paths] << [target.name.to_s, path.to_s]
237
+ end
238
+ end
239
+ end
240
+
135
241
  def print_expectations(project:, all_files:, expectations_path:, notifications:)
136
242
  expectations = Expectations.load(path: expectations_path, content: expectations_path.read)
137
243
 
@@ -53,7 +53,7 @@ module Steep
53
53
  nil
54
54
  else
55
55
  command_line_args
56
- end
56
+ end #: Array[String]?
57
57
 
58
58
  if ruby_patterns
59
59
  loader.each_path_in_patterns(target.source_pattern, ruby_patterns) do |path|
@@ -69,7 +69,7 @@ module Steep
69
69
  nil
70
70
  else
71
71
  command_line_args
72
- end
72
+ end #: Array[String]
73
73
 
74
74
  if rbs_patterns
75
75
  loader.each_path_in_patterns(target.signature_pattern, rbs_patterns) do |path|
@@ -79,10 +79,10 @@ module Steep
79
79
  end
80
80
 
81
81
  stdin_input.each_key do |path|
82
- case ts = project.targets_for_path(path)
83
- when Array
82
+ case
83
+ when project.target_for_signature_path(path)
84
84
  signature_paths << path
85
- when Project::Target
85
+ when project.target_for_source_path(path)
86
86
  target_paths << path
87
87
  end
88
88
  end
@@ -156,13 +156,15 @@ module Steep
156
156
 
157
157
  request_guid = master.fresh_request_id()
158
158
  progress = master.work_done_progress(request_guid)
159
- request = Server::Master::TypeCheckRequest.new(guid: request_guid, progress: progress)
159
+ request = Server::TypeCheckController::Request.new(guid: request_guid, progress: progress)
160
160
 
161
161
  target_paths.each do |path|
162
- request.code_paths << project.absolute_path(path)
162
+ target = project.target_for_source_path(path) or next
163
+ request.code_paths << [target.name, project.absolute_path(path)]
163
164
  end
164
165
  signature_paths.each do |path|
165
- request.signature_paths << project.absolute_path(path)
166
+ target = project.target_for_signature_path(path) or next
167
+ request.signature_paths << [target.name, project.absolute_path(path)]
166
168
  end
167
169
 
168
170
  request.needs_response = true
@@ -1,68 +1,111 @@
1
+ require "active_support/core_ext/hash/keys"
2
+
1
3
  module Steep
2
4
  module Drivers
3
5
  class PrintProject
4
6
  attr_reader :stdout
5
7
  attr_reader :stderr
6
8
 
9
+ attr_accessor :print_files
10
+ attr_reader :files
11
+
7
12
  include Utils::DriverHelper
8
13
 
9
14
  def initialize(stdout:, stderr:)
10
15
  @stdout = stdout
11
16
  @stderr = stderr
17
+ @print_files = false
12
18
  end
13
19
 
14
- def run
15
- project = load_config()
16
-
17
- loader = Services::FileLoader.new(base_dir: project.base_dir)
18
-
19
- project.targets.each do |target|
20
- source_changes = loader.load_changes(target.source_pattern, changes: {})
21
- signature_changes = loader.load_changes(target.signature_pattern, changes: {})
22
-
23
- stdout.puts "Target:"
24
- stdout.puts " #{target.name}:"
25
- stdout.puts " sources:"
26
- stdout.puts " patterns:"
27
- target.source_pattern.patterns.each do |pattern|
28
- stdout.puts " - #{pattern}"
29
- end
30
- stdout.puts " ignores:"
31
- target.source_pattern.ignores.each do |pattern|
32
- stdout.puts " - #{pattern}"
33
- end
34
- stdout.puts " files:"
35
- source_changes.each_key do |path|
36
- stdout.puts " - #{path}"
20
+ def as_json(project)
21
+ {
22
+ steepfile: project.steepfile_path.to_s,
23
+ targets: project.targets.map do |target|
24
+ target_as_json(target)
37
25
  end
38
- stdout.puts " signatures:"
39
- stdout.puts " patterns:"
40
- target.signature_pattern.patterns.each do |pattern|
41
- stdout.puts " - #{pattern}"
42
- end
43
- stdout.puts " files:"
44
- signature_changes.each_key do |path|
45
- stdout.puts " - #{path}"
46
- end
47
- stdout.puts " libraries:"
48
- target.options.libraries.each do |lib|
49
- stdout.puts " - #{lib}"
50
- end
51
- stdout.puts " library dirs:"
52
- target.new_env_loader(project: project).tap do |loader|
26
+ }.stringify_keys
27
+ end
28
+
29
+ def target_as_json(target)
30
+ json = {
31
+ "name" => target.name.to_s,
32
+ "source_pattern" => pattern_as_json(target.source_pattern),
33
+ "signature_pattern" => pattern_as_json(target.signature_pattern),
34
+ "groups" => target.groups.map do |group|
35
+ group_as_json(group)
36
+ end,
37
+ "libraries" => target.new_env_loader().yield_self do |loader|
38
+ libs = [] #: Array[library_json]
53
39
  loader.each_dir do |lib, path|
54
40
  case lib
55
41
  when :core
56
- stdout.puts " - core: #{path}"
42
+ libs << { "name" => "__core__", "path" => path.to_s }
57
43
  when Pathname
58
44
  raise "Unexpected pathname from loader: path=#{path}"
59
45
  else
60
- stdout.puts " - #{lib.name}(#{lib.version}): #{path}"
46
+ libs << { "name" => lib.name, "version" => lib.version, "path" => path.to_s }
61
47
  end
62
48
  end
49
+ libs
50
+ end,
51
+ "unreferenced" => target.unreferenced
52
+ } #: target_json
53
+
54
+ if files
55
+ files.each_group_signature_path(target, true) do |path|
56
+ (json["signature_paths"] ||= []) << path.to_s
57
+ end
58
+ files.each_group_source_path(target, true) do |path|
59
+ (json["source_paths"] ||= []) << path.to_s
63
60
  end
64
61
  end
65
62
 
63
+ json
64
+ end
65
+
66
+ def group_as_json(group)
67
+ json = {
68
+ "name" => group.name.to_s,
69
+ "source_pattern" => pattern_as_json(group.source_pattern),
70
+ "signature_pattern" => pattern_as_json(group.signature_pattern)
71
+ } #: group_json
72
+
73
+ if files
74
+ files.each_group_signature_path(group, true) do |path|
75
+ (json["signature_paths"] ||= []) << path.to_s
76
+
77
+ end
78
+ files.each_group_source_path(group, true) do |path|
79
+ (json["source_paths"] ||= []) << path.to_s
80
+ end
81
+ end
82
+
83
+ json
84
+ end
85
+
86
+ def pattern_as_json(pattern)
87
+ {
88
+ "pattern" => pattern.patterns,
89
+ "ignore" => pattern.ignores
90
+ }
91
+ end
92
+
93
+ def run
94
+ project = load_config()
95
+ if print_files
96
+ loader = Services::FileLoader.new(base_dir: project.base_dir)
97
+ @files = files = Server::TargetGroupFiles.new(project)
98
+ project.targets.each do |target|
99
+ loader.each_path_in_target(target) do |path|
100
+ files.add_path(path)
101
+ end
102
+ end
103
+ else
104
+ @files = nil
105
+ end
106
+
107
+ stdout.puts YAML.dump(as_json(project))
108
+
66
109
  0
67
110
  end
68
111
  end
@@ -13,9 +13,11 @@ module Steep
13
13
  else
14
14
  Steep.ui_logger.error { "Cannot find a configuration at #{path}: `steep init` to scaffold. Using current directory..." }
15
15
  Project.new(steepfile_path: nil, base_dir: Pathname.pwd).tap do |project|
16
- Project::DSL.new(project: project).target :'.' do
17
- check '.'
18
- signature '.'
16
+ Project::DSL.eval(project) do
17
+ target :'.' do
18
+ check '.'
19
+ signature '.'
20
+ end
19
21
  end
20
22
  end
21
23
  end.tap do |project|
@@ -112,7 +112,19 @@ module Steep
112
112
  end
113
113
  end
114
114
 
115
- client_writer.write(Server::CustomMethods::TypeCheck.request(SecureRandom.uuid, { guid: nil }))
115
+ params = { library_paths: [], signature_paths: [], code_paths: [] } #: Server::CustomMethods::TypeCheck::params
116
+
117
+ (modified + added).each do |path|
118
+ path = Pathname(path)
119
+ if target = project.target_for_source_path(path)
120
+ params[:code_paths] << [target.name.to_s, path.to_s]
121
+ end
122
+ if target = project.target_for_signature_path(path)
123
+ params[:signature_paths] << [target.name.to_s, path.to_s]
124
+ end
125
+ end
126
+
127
+ client_writer.write(Server::CustomMethods::TypeCheck.request(SecureRandom.uuid, params))
116
128
 
117
129
  stdout.puts Rainbow("done!").bold
118
130
  end.tap(&:start)
@@ -120,7 +132,17 @@ module Steep
120
132
  begin
121
133
  stdout.puts Rainbow("👀 Watching directories, Ctrl-C to stop.").bold
122
134
 
123
- client_writer.write(Server::CustomMethods::TypeCheck.request(SecureRandom.uuid, { guid: nil }))
135
+ params = { library_paths: [], signature_paths: [], code_paths: [] } #: Server::CustomMethods::TypeCheck::params
136
+ file_loader = Services::FileLoader.new(base_dir: project.base_dir)
137
+ project.targets.each do |target|
138
+ file_loader.each_path_in_patterns(target.source_pattern, dirs.map(&:to_s)) do |path|
139
+ params[:code_paths] << [target.name.to_s, project.absolute_path(path).to_s]
140
+ end
141
+ file_loader.each_path_in_patterns(target.signature_pattern, dirs.map(&:to_s)) do |path|
142
+ params[:signature_paths] << [target.name.to_s, project.absolute_path(path).to_s]
143
+ end
144
+ end
145
+ client_writer.write(Server::CustomMethods::TypeCheck.request(SecureRandom.uuid, params))
124
146
 
125
147
  client_reader.read do |response|
126
148
  case response[:method]