steep 0.41.0 → 0.42.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -0
  3. data/lib/steep.rb +80 -12
  4. data/lib/steep/ast/types/class.rb +4 -0
  5. data/lib/steep/cli.rb +21 -3
  6. data/lib/steep/diagnostic/ruby.rb +0 -4
  7. data/lib/steep/diagnostic/signature.rb +135 -2
  8. data/lib/steep/drivers/annotations.rb +18 -34
  9. data/lib/steep/drivers/check.rb +22 -15
  10. data/lib/steep/drivers/diagnostic_printer.rb +7 -2
  11. data/lib/steep/drivers/langserver.rb +3 -8
  12. data/lib/steep/drivers/print_project.rb +10 -9
  13. data/lib/steep/drivers/stats.rb +10 -14
  14. data/lib/steep/drivers/utils/jobs_count.rb +9 -0
  15. data/lib/steep/drivers/validate.rb +29 -18
  16. data/lib/steep/drivers/watch.rb +43 -39
  17. data/lib/steep/drivers/worker.rb +11 -8
  18. data/lib/steep/index/signature_symbol_provider.rb +9 -1
  19. data/lib/steep/project.rb +0 -36
  20. data/lib/steep/project/dsl.rb +5 -3
  21. data/lib/steep/project/pattern.rb +56 -0
  22. data/lib/steep/project/target.rb +9 -225
  23. data/lib/steep/server/base_worker.rb +1 -3
  24. data/lib/steep/server/change_buffer.rb +63 -0
  25. data/lib/steep/server/interaction_worker.rb +72 -56
  26. data/lib/steep/server/master.rb +28 -82
  27. data/lib/steep/server/type_check_worker.rb +122 -0
  28. data/lib/steep/server/worker_process.rb +11 -9
  29. data/lib/steep/{project → services}/completion_provider.rb +3 -3
  30. data/lib/steep/services/content_change.rb +61 -0
  31. data/lib/steep/services/file_loader.rb +48 -0
  32. data/lib/steep/{project → services}/hover_content.rb +14 -16
  33. data/lib/steep/services/path_assignment.rb +29 -0
  34. data/lib/steep/services/signature_service.rb +369 -0
  35. data/lib/steep/services/stats_calculator.rb +69 -0
  36. data/lib/steep/services/type_check_service.rb +342 -0
  37. data/lib/steep/signature/validator.rb +171 -77
  38. data/lib/steep/subtyping/check.rb +246 -45
  39. data/lib/steep/subtyping/constraints.rb +2 -2
  40. data/lib/steep/type_construction.rb +138 -46
  41. data/lib/steep/type_inference/local_variable_type_env.rb +26 -12
  42. data/lib/steep/type_inference/logic_type_interpreter.rb +1 -1
  43. data/lib/steep/type_inference/type_env.rb +43 -17
  44. data/lib/steep/version.rb +1 -1
  45. data/smoke/diagnostics-rbs-duplicated/test_expectations.yml +1 -1
  46. data/smoke/diagnostics-rbs/Steepfile +7 -4
  47. data/smoke/diagnostics-rbs/test_expectations.yml +23 -21
  48. data/smoke/diagnostics-rbs/unknown-type-name-2.rbs +5 -0
  49. data/smoke/extension/f.rb +2 -0
  50. data/smoke/extension/f.rbs +3 -0
  51. data/smoke/extension/test_expectations.yml +12 -0
  52. data/smoke/tsort/Steepfile +2 -0
  53. data/smoke/tsort/test_expectations.yml +20 -0
  54. data/smoke/unexpected/Steepfile +5 -0
  55. data/smoke/unexpected/test_expectations.yml +25 -0
  56. data/smoke/unexpected/unexpected.rb +1 -0
  57. data/smoke/unexpected/unexpected.rbs +3 -0
  58. data/steep.gemspec +2 -1
  59. metadata +41 -17
  60. data/lib/steep/project/file_loader.rb +0 -68
  61. data/lib/steep/project/signature_file.rb +0 -39
  62. data/lib/steep/project/source_file.rb +0 -129
  63. data/lib/steep/project/stats_calculator.rb +0 -80
  64. data/lib/steep/server/code_worker.rb +0 -150
  65. data/lib/steep/server/signature_worker.rb +0 -157
  66. data/lib/steep/server/utils.rb +0 -69
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7fe01659cf0cfc1c7063fede02ec238b5772bb6c6fdf44cf501ca555c719c47c
4
- data.tar.gz: d74ebe84a911514eef46cd92a14dfedc0b90e491aa9bf284f82325a9c4a9c2b4
3
+ metadata.gz: 3bed885aa8ba3f60076879eb1ca1572c56ae59aae2a9ee3745affbbd1f3f93d2
4
+ data.tar.gz: 344c77c6676f8c6772d28bab9598c8fa45835100f24603985750de076ebe57f3
5
5
  SHA512:
6
- metadata.gz: cd2459353ab367c913f0308b1cb0dd95d297cce18ea3bb4ff537612edc0b8adc2ef4530d4bf8203c6c777fe57b8bccfbf8a8714ebc0ede67400a030e6ea1348f
7
- data.tar.gz: b3ee38f5e340f05420783dc3f8a31ac662f475ec7bcef82222e5f07360faac1235249fa903c721a1d322b7999034b74e7f812fa47c3d3dec8a9f5763fa2693fb
6
+ metadata.gz: dce04d256960ee738d029a9c66187a1ef5f11beb3fd0613cbb02dde6494eeafde8aa0bf12aadc02d07bb6a64a785444f18636df1eaa3f1be02bce1d24ad63385
7
+ data.tar.gz: df9772b46abe7c2acd10cf497ded086b3614016d74b26578d2da6720f26afa01a73a7b43c6a0170b67157e7615e2ec989597ed1081a3f6e4ac69553adc338589
data/CHANGELOG.md CHANGED
@@ -2,6 +2,15 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.42.0 (2021-03-08)
6
+
7
+ * Type checking performance improvement ([\#309](https://github.com/soutaro/steep/pull/309), [\#311](https://github.com/soutaro/steep/pull/311), [\#312](https://github.com/soutaro/steep/pull/312), [\#313](https://github.com/soutaro/steep/pull/313), [\#314](https://github.com/soutaro/steep/pull/314), [\#315](https://github.com/soutaro/steep/pull/315), [\#316](https://github.com/soutaro/steep/pull/316), [\#320](https://github.com/soutaro/steep/pull/320), [\#322](https://github.com/soutaro/steep/pull/322))
8
+ * Let `watch` command support files ([\#323](https://github.com/soutaro/steep/pull/323))
9
+ * Validate _module-self-type_ constraints ([\#308](https://github.com/soutaro/steep/pull/308))
10
+ * Add `-j` option to specify number of worker processes ([\#318](https://github.com/soutaro/steep/pull/318), [\#325](https://github.com/soutaro/steep/pull/325))
11
+ * Fix `code` of RBS diagnostics ([\#306](https://github.com/soutaro/steep/pull/306))
12
+ * Skip printing source code from out of date _expectations_ file ([\#305](https://github.com/soutaro/steep/pull/305))
13
+
5
14
  ## 0.41.0 (2021-02-07)
6
15
 
7
16
  * Add `--with-expectations` and `--save-expectations` option ([#303](https://github.com/soutaro/steep/pull/303))
data/lib/steep.rb CHANGED
@@ -16,6 +16,8 @@ require "stringio"
16
16
  require 'uri'
17
17
  require "yaml"
18
18
 
19
+ require "parallel/processor_count"
20
+
19
21
  require "rbs"
20
22
 
21
23
  require "steep/method_name"
@@ -86,27 +88,31 @@ require "steep/index/rbs_index"
86
88
  require "steep/index/signature_symbol_provider"
87
89
  require "steep/index/source_index"
88
90
 
89
- require "steep/server/utils"
91
+ require "steep/server/change_buffer"
90
92
  require "steep/server/base_worker"
91
- require "steep/server/code_worker"
92
- require "steep/server/signature_worker"
93
93
  require "steep/server/worker_process"
94
94
  require "steep/server/interaction_worker"
95
+ require "steep/server/type_check_worker"
95
96
  require "steep/server/master"
96
97
 
98
+ require "steep/services/content_change"
99
+ require "steep/services/path_assignment"
100
+ require "steep/services/signature_service"
101
+ require "steep/services/type_check_service"
102
+ require "steep/services/hover_content"
103
+ require "steep/services/completion_provider"
104
+ require "steep/services/stats_calculator"
105
+ require "steep/services/file_loader"
106
+
97
107
  require "steep/project"
98
- require "steep/project/signature_file"
99
- require "steep/project/source_file"
108
+ require "steep/project/pattern"
100
109
  require "steep/project/options"
101
110
  require "steep/project/target"
102
111
  require "steep/project/dsl"
103
- require "steep/project/file_loader"
104
- require "steep/project/hover_content"
105
- require "steep/project/completion_provider"
106
- require "steep/project/stats_calculator"
107
112
 
108
113
  require "steep/expectations"
109
114
  require "steep/drivers/utils/driver_helper"
115
+ require "steep/drivers/utils/jobs_count"
110
116
  require "steep/drivers/check"
111
117
  require "steep/drivers/stats"
112
118
  require "steep/drivers/validate"
@@ -134,7 +140,7 @@ module Steep
134
140
  def self.new_logger(output, prev_level)
135
141
  ActiveSupport::TaggedLogging.new(Logger.new(output)).tap do |logger|
136
142
  logger.push_tags "Steep #{VERSION}"
137
- logger.level = prev_level || Logger::WARN
143
+ logger.level = prev_level || Logger::ERROR
138
144
  end
139
145
  end
140
146
 
@@ -151,11 +157,14 @@ module Steep
151
157
  @logger = nil
152
158
  self.log_output = STDERR
153
159
 
154
- def self.measure(message)
160
+ def self.measure(message, level: :warn)
155
161
  start = Time.now
156
162
  yield.tap do
157
163
  time = Time.now - start
158
- self.logger.info "#{message} took #{time} seconds"
164
+ if level.is_a?(Symbol)
165
+ level = Logger.const_get(level.to_s.upcase)
166
+ end
167
+ self.logger.log(level) { "#{message} took #{time} seconds" }
159
168
  end
160
169
  end
161
170
 
@@ -165,4 +174,63 @@ module Steep
165
174
  Steep.logger.warn " #{loc}"
166
175
  end
167
176
  end
177
+
178
+ class Sampler
179
+ def initialize()
180
+ @samples = []
181
+ end
182
+
183
+ def sample(message)
184
+ start = Time.now
185
+ yield.tap do
186
+ time = Time.now - start
187
+ @samples << [message, time]
188
+ end
189
+ end
190
+
191
+ def count
192
+ @samples.count
193
+ end
194
+
195
+ def total
196
+ @samples.sum(&:last)
197
+ end
198
+
199
+ def slowests(num)
200
+ @samples.sort_by(&:last).reverse.take(num)
201
+ end
202
+
203
+ def average
204
+ if count > 0
205
+ total/count
206
+ else
207
+ 0
208
+ end
209
+ end
210
+
211
+ def percentile(p)
212
+ slowests(count - count * p / 100r).last&.last || 0
213
+ end
214
+ end
215
+
216
+ def self.measure2(message, level: :warn)
217
+ sampler = Sampler.new
218
+ result = yield(sampler)
219
+
220
+ if level.is_a?(Symbol)
221
+ level = Logger.const_get(level.to_s.upcase)
222
+ end
223
+ logger.log(level) { "#{sampler.total}secs for \"#{message}\"" }
224
+ logger.log(level) { " Average: #{sampler.average}secs"}
225
+ logger.log(level) { " Median: #{sampler.percentile(50)}secs"}
226
+ logger.log(level) { " Samples: #{sampler.count}"}
227
+ logger.log(level) { " 99 percentile: #{sampler.percentile(99)}secs"}
228
+ logger.log(level) { " 90 percentile: #{sampler.percentile(90)}secs"}
229
+ logger.log(level) { " 10 Slowests:"}
230
+ sampler.slowests(10).each do |message, time|
231
+ logger.log(level) { " #{message} (#{time}secs)"}
232
+ end
233
+
234
+ result
235
+ end
168
236
  end
@@ -8,6 +8,10 @@ module Steep
8
8
  @location = location
9
9
  end
10
10
 
11
+ def to_s
12
+ "class"
13
+ end
14
+
11
15
  def ==(other)
12
16
  other.is_a?(Class)
13
17
  end
data/lib/steep/cli.rb CHANGED
@@ -8,6 +8,8 @@ module Steep
8
8
  attr_reader :stderr
9
9
  attr_reader :command
10
10
 
11
+ include Parallel::ProcessorCount
12
+
11
13
  def initialize(stdout:, stdin:, stderr:, argv:)
12
14
  @stdout = stdout
13
15
  @stdin = stdin
@@ -64,6 +66,14 @@ module Steep
64
66
  end
65
67
  end
66
68
 
69
+ def handle_jobs_option(command, opts, modifier = 0)
70
+ default = physical_processor_count + modifier
71
+ command.jobs_count = default
72
+ opts.on("-j N", "--jobs=N", "Specify the number of type check workers (defaults: #{default})") do |count|
73
+ command.jobs_count = Integer(count)
74
+ end
75
+ end
76
+
67
77
  def process_init
68
78
  Drivers::Init.new(stdout: stdout, stderr: stderr).tap do |command|
69
79
  OptionParser.new do |opts|
@@ -89,6 +99,7 @@ module Steep
89
99
  opts.on("--save-expectations[=PATH]", "Save expectations with current type check result to PATH (or steep_expectations.yml)") do |path|
90
100
  check.save_expectations_path = Pathname(path || "steep_expectations.yml")
91
101
  end
102
+ handle_jobs_option check, opts
92
103
  handle_logging_options opts
93
104
  end.parse!(argv)
94
105
 
@@ -102,6 +113,7 @@ module Steep
102
113
  opts.banner = "Usage: steep stats [options] [sources]"
103
114
 
104
115
  opts.on("--steepfile=PATH") {|path| check.steepfile = Pathname(path) }
116
+ handle_jobs_option check, opts
105
117
  handle_logging_options opts
106
118
  end.parse!(argv)
107
119
 
@@ -142,10 +154,12 @@ module Steep
142
154
  Drivers::Watch.new(stdout: stdout, stderr: stderr).tap do |command|
143
155
  OptionParser.new do |opts|
144
156
  opts.banner = "Usage: steep watch [options] [dirs]"
157
+ handle_jobs_option command, opts
145
158
  handle_logging_options opts
146
159
  end.parse!(argv)
147
160
 
148
- command.dirs.push *argv
161
+ dirs = argv.map {|dir| Pathname(dir) }
162
+ command.dirs.push(*dirs)
149
163
  end.run
150
164
  end
151
165
 
@@ -153,6 +167,7 @@ module Steep
153
167
  Drivers::Langserver.new(stdout: stdout, stderr: stderr, stdin: stdin).tap do |command|
154
168
  OptionParser.new do |opts|
155
169
  opts.on("--steepfile=PATH") {|path| command.steepfile = Pathname(path) }
170
+ handle_jobs_option command, opts, -1
156
171
  handle_logging_options opts
157
172
  end.parse!(argv)
158
173
  end.run
@@ -185,12 +200,15 @@ module Steep
185
200
  handle_logging_options opts
186
201
 
187
202
  opts.on("--interaction") { command.worker_type = :interaction }
188
- opts.on("--code") { command.worker_type = :code }
189
- opts.on("--signature") { command.worker_type = :signature }
203
+ opts.on("--typecheck") { command.worker_type = :typecheck }
190
204
  opts.on("--steepfile=PATH") {|path| command.steepfile = Pathname(path) }
191
205
  opts.on("--name=NAME") {|name| command.worker_name = name }
192
206
  opts.on("--delay-shutdown") { command.delay_shutdown = true }
207
+ opts.on("--max-index=COUNT") {|count| command.max_index = Integer(count) }
208
+ opts.on("--index=INDEX") {|index| command.index = Integer(index) }
193
209
  end.parse!(argv)
210
+
211
+ command.commandline_args.push(*argv)
194
212
  end.run
195
213
  end
196
214
  end
@@ -613,10 +613,6 @@ module Steep
613
613
  def header_line
614
614
  "UnexpectedError: #{error.message}"
615
615
  end
616
-
617
- def detail_lines
618
- error.backtrace.join("\n")
619
- end
620
616
  end
621
617
  end
622
618
  end
@@ -21,7 +21,7 @@ module Steep
21
21
  end
22
22
 
23
23
  def diagnostic_code
24
- "Ruby::#{error_name}"
24
+ "RBS::#{error_name}"
25
25
  end
26
26
 
27
27
  def path
@@ -38,7 +38,21 @@ module Steep
38
38
  end
39
39
 
40
40
  def header_line
41
- "Syntax error: #{exception.message}"
41
+ if exception.is_a?(RBS::Parser::SyntaxError)
42
+ value = if exception.error_value.is_a?(RBS::Parser::LocatedValue)
43
+ exception.error_value.value
44
+ else
45
+ exception.error_value
46
+ end
47
+ string = value.to_s
48
+ unless string.empty?
49
+ string = " (#{string})"
50
+ end
51
+
52
+ "Syntax error caused by token `#{exception.token_str}`#{string}"
53
+ else
54
+ exception.message
55
+ end
42
56
  end
43
57
  end
44
58
 
@@ -219,6 +233,125 @@ module Steep
219
233
  "The variance of type parameter `#{param.name}` is #{param.variance}, but used in incompatible position here"
220
234
  end
221
235
  end
236
+
237
+ class ModuleSelfTypeError < Base
238
+ attr_reader :name
239
+ attr_reader :ancestor
240
+ attr_reader :relation
241
+
242
+ def initialize(name:, ancestor:, relation:, location:)
243
+ super(location: location)
244
+
245
+ @name = name
246
+ @ancestor = ancestor
247
+ @relation = relation
248
+ end
249
+
250
+ def header_line
251
+ "Module self type constraint in type `#{name}` doesn't satisfy: `#{relation}`"
252
+ end
253
+ end
254
+
255
+ class InstanceVariableTypeError < Base
256
+ attr_reader :name
257
+ attr_reader :variable
258
+ attr_reader :var_type
259
+ attr_reader :parent_type
260
+
261
+ def initialize(name:, location:, var_type:, parent_type:)
262
+ super(location: location)
263
+
264
+ @name = name
265
+ @var_type = var_type
266
+ @parent_type = parent_type
267
+ end
268
+
269
+ def header_line
270
+ "Instance variable cannot have different type with parents: #{var_type} <=> #{parent_type}"
271
+ end
272
+ end
273
+
274
+ def self.from_rbs_error(error, factory:)
275
+ case error
276
+ when RBS::Parser::SemanticsError, RBS::Parser::LexerError
277
+ Diagnostic::Signature::SyntaxError.new(error, location: error.location)
278
+ when RBS::Parser::SyntaxError
279
+ Diagnostic::Signature::SyntaxError.new(error, location: error.error_value.location)
280
+ when RBS::DuplicatedDeclarationError
281
+ Diagnostic::Signature::DuplicatedDeclaration.new(
282
+ type_name: error.name,
283
+ location: error.decls[0].location
284
+ )
285
+ when RBS::GenericParameterMismatchError
286
+ Diagnostic::Signature::GenericParameterMismatch.new(
287
+ name: error.name,
288
+ location: error.decl.location
289
+ )
290
+ when RBS::InvalidTypeApplicationError
291
+ Diagnostic::Signature::InvalidTypeApplication.new(
292
+ name: error.type_name,
293
+ args: error.args.map {|ty| factory.type(ty) },
294
+ params: error.params,
295
+ location: error.location
296
+ )
297
+ when RBS::NoTypeFoundError,
298
+ RBS::NoSuperclassFoundError,
299
+ RBS::NoMixinFoundError,
300
+ RBS::NoSelfTypeFoundError
301
+ Diagnostic::Signature::UnknownTypeName.new(
302
+ name: error.type_name,
303
+ location: error.location
304
+ )
305
+ when RBS::InvalidOverloadMethodError
306
+ Diagnostic::Signature::InvalidMethodOverload.new(
307
+ class_name: error.type_name,
308
+ method_name: error.method_name,
309
+ location: error.members[0].location
310
+ )
311
+ when RBS::DuplicatedMethodDefinitionError
312
+ Diagnostic::Signature::DuplicatedMethodDefinition.new(
313
+ class_name: error.type_name,
314
+ method_name: error.method_name,
315
+ location: error.location
316
+ )
317
+ when RBS::DuplicatedInterfaceMethodDefinitionError
318
+ Diagnostic::Signature::DuplicatedMethodDefinition.new(
319
+ class_name: error.type_name,
320
+ method_name: error.method_name,
321
+ location: error.member.location
322
+ )
323
+ when RBS::UnknownMethodAliasError
324
+ Diagnostic::Signature::UnknownMethodAlias.new(
325
+ class_name: error.type_name,
326
+ method_name: error.original_name,
327
+ location: error.location
328
+ )
329
+ when RBS::RecursiveAliasDefinitionError
330
+ Diagnostic::Signature::RecursiveAlias.new(
331
+ class_name: error.type.name,
332
+ names: error.defs.map(&:name),
333
+ location: error.defs[0].original.location
334
+ )
335
+ when RBS::RecursiveAncestorError
336
+ Diagnostic::Signature::RecursiveAncestor.new(
337
+ ancestors: error.ancestors,
338
+ location: error.location
339
+ )
340
+ when RBS::SuperclassMismatchError
341
+ Diagnostic::Signature::SuperclassMismatch.new(
342
+ name: error.name,
343
+ location: error.entry.primary.decl.location
344
+ )
345
+ when RBS::InvalidVarianceAnnotationError
346
+ Diagnostic::Signature::InvalidVarianceAnnotation.new(
347
+ name: error.type_name,
348
+ param: error.param,
349
+ location: error.location
350
+ )
351
+ else
352
+ raise error
353
+ end
354
+ end
222
355
  end
223
356
  end
224
357
  end
@@ -19,50 +19,34 @@ module Steep
19
19
  def run
20
20
  project = load_config()
21
21
 
22
- loader = Project::FileLoader.new(project: project)
23
- loader.load_sources(command_line_patterns)
24
- loader.load_signatures()
22
+ loader = Services::FileLoader.new(base_dir: project.base_dir)
25
23
 
26
24
  project.targets.each do |target|
27
25
  Steep.logger.tagged "target=#{target.name}" do
28
- target.load_signatures(validate: false) do |_, subtyping, _|
29
- case (status = target.status)
30
- when nil # status set on error cases
31
- target.source_files.each_value do |file|
32
- file.parse(subtyping.factory) do |source|
33
- source.each_annotation.sort_by {|node, _| [node.loc.expression.begin_pos, node.loc.expression.end_pos] }.each do |node, annotations|
34
- loc = node.loc
35
- stdout.puts "#{file.path}:#{loc.line}:#{loc.column}:#{node.type}:\t#{node.loc.expression.source.lines.first}"
36
- annotations.each do |annotation|
37
- stdout.puts " #{annotation.location.source}"
38
- end
39
- end
40
- end
41
- end
42
- when Project::Target::SignatureErrorStatus
43
- formatter = Diagnostic::LSPFormatter.new
44
- diagnostics = status.errors.group_by {|e| e.location.buffer }.transform_values do |errors|
45
- errors.map {|error| formatter.format(error) }
46
- end
26
+ service = Services::SignatureService.load_from(target.new_env_loader)
27
+
28
+ sigs = loader.load_changes(target.signature_pattern, changes: {})
29
+ service.update(sigs)
30
+
31
+ factory = AST::Types::Factory.new(builder: service.latest_builder)
32
+
33
+ srcs = loader.load_changes(target.source_pattern, command_line_patterns, changes: {})
34
+ srcs.each do |path, changes|
35
+ text = changes.inject("") {|text, change| change.apply_to(text) }
36
+ source = Source.parse(text, path: path, factory: factory)
47
37
 
48
- diagnostics.each do |buffer, ds|
49
- printer = DiagnosticPrinter.new(stdout: stdout, buffer: buffer)
50
- ds.each do |d|
51
- printer.print(d)
52
- stdout.puts
53
- end
38
+ source.each_annotation.sort_by {|node, _| [node.loc.expression.begin_pos, node.loc.expression.end_pos] }.each do |node, annotations|
39
+ loc = node.loc
40
+ stdout.puts "#{path}:#{loc.line}:#{loc.column}:#{node.type}:\t#{node.loc.expression.source.lines.first}"
41
+ annotations.each do |annotation|
42
+ stdout.puts " #{annotation.location.source}"
54
43
  end
55
44
  end
56
45
  end
57
46
  end
58
47
  end
59
48
 
60
- project.targets.each do |target|
61
- Steep.logger.tagged "target=#{target.name}" do
62
- end
63
- end
64
-
65
- project.targets.all? {|target| !target.status } ? 0 : 1
49
+ 0
66
50
  end
67
51
  end
68
52
  end