rbs 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d175f17e9f1226e0cb0d37c2167b3b52b0e736661d1406937922194c68adfd54
4
- data.tar.gz: 204d38937da751f3ea15dfd64370e379689e54f264b63be54e6c4843c4827579
3
+ metadata.gz: a2e86d5e87d89f97eed8e2674aa5f5035413179ba104a5cb265ab748268c51fe
4
+ data.tar.gz: 9d58fa00413d5a334496ee688bbc72520e1911558f39ad2d01b180b790e5d894
5
5
  SHA512:
6
- metadata.gz: 242ffa432db2a94a59636be87e261411c0bf465ac170b6f5b52955cb671d2c70e6eaed7dc74b489868117fcaa360df33c16ed6e2e472edd96663491c1211d793
7
- data.tar.gz: 6ccb639e3a73a7e4794f906e9e125dd173d0406198a11511592e3c3492126c31a5ff1798010087fb19d4eb053ba46140e42f869b913ae3b7aaee20303ef3f92c
6
+ metadata.gz: 328850c1f912cd7cc45e1c210140c098206f668c0400a817cde00e36dec1591ec235b5b6a1255b0e66d585745d4f6f7effeb09f28ae2a7536091852f9ba8bc89
7
+ data.tar.gz: 96bc5adc81b98d723a98d20dcbeef13424fb0a4267272ff1ad6daaab5ef310f24c038f4e23793253beade1e55a00a6eece457697a3a4ec62413f08b7c42ace99
@@ -2,6 +2,13 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.8.0 (2020-08-01)
6
+
7
+ * Signature updates for `Enumerator` and `PTY`
8
+ * Fix prototype rb/rbi error handling [#349](https://github.com/ruby/rbs/pull/349)
9
+ * Runtime test improvements [#344](https://github.com/ruby/rbs/pull/344), [#343](https://github.com/ruby/rbs/pull/343)
10
+ * Add `...` syntax [#342](https://github.com/ruby/rbs/pull/342)
11
+
5
12
  ## 0.7.0 (2020-07-20)
6
13
 
7
14
  * Add `DefinitionBuilder#one_instance_ancestors` and `DefinitionBuilder#one_singleton_ancestors` [#341](https://github.com/ruby/rbs/pull/341)
@@ -66,6 +66,10 @@ module RBS
66
66
  opts
67
67
  end
68
68
 
69
+ def has_parser?
70
+ defined?(RubyVM::AbstractSyntaxTree)
71
+ end
72
+
69
73
  def run(args)
70
74
  options = LibraryOptions.new
71
75
 
@@ -599,12 +603,18 @@ EOU
599
603
  end
600
604
 
601
605
  def run_prototype_file(format, args)
606
+ availability = unless has_parser?
607
+ "\n** This command does not work on this interpreter (#{RUBY_ENGINE}) **\n"
608
+ end
609
+
602
610
  opts = OptionParser.new
603
611
  opts.banner = <<EOU
604
612
  Usage: rbs prototype #{format} [options...] [files...]
605
-
613
+ #{availability}
606
614
  Generate RBS prototype from source code.
607
- It parses specified Ruby code and and generates RBS prototypes.
615
+ It parses specified Ruby code and and generates RBS prototypes.
616
+
617
+ It only works on MRI because it parses Ruby code with `RubyVM::AbstractSyntaxTree`.
608
618
 
609
619
  Examples:
610
620
 
@@ -613,6 +623,11 @@ Examples:
613
623
  EOU
614
624
  opts.parse!(args)
615
625
 
626
+ unless has_parser?
627
+ stdout.puts "Not supported on this interpreter (#{RUBY_ENGINE})."
628
+ exit 1
629
+ end
630
+
616
631
  if args.empty?
617
632
  stdout.puts opts
618
633
  return nil
@@ -4,9 +4,9 @@ class RBS::Parser
4
4
  tANNOTATION
5
5
  tSTRING tSYMBOL tINTEGER tWRITE_ATTR
6
6
  kLPAREN kRPAREN kLBRACKET kRBRACKET kLBRACE kRBRACE
7
- kVOID kNIL kTRUE kFALSE kANY kUNTYPED kTOP kBOT kSELF kSELFQ kINSTANCE kCLASS kBOOL kSINGLETON kTYPE kDEF kMODULE kSUPER
7
+ kVOID kNIL kTRUE kFALSE kANY kUNTYPED kTOP kBOT kSELF kSELFQ kINSTANCE kCLASS kBOOL kSINGLETON kTYPE kDEF kMODULE
8
8
  kPRIVATE kPUBLIC kALIAS
9
- kCOLON kCOLON2 kCOMMA kBAR kAMP kHAT kARROW kQUESTION kEXCLAMATION kSTAR kSTAR2 kFATARROW kEQ kDOT kLT
9
+ kCOLON kCOLON2 kCOMMA kBAR kAMP kHAT kARROW kQUESTION kEXCLAMATION kSTAR kSTAR2 kFATARROW kEQ kDOT kDOT3 kLT
10
10
  kINTERFACE kEND kINCLUDE kEXTEND kATTRREADER kATTRWRITER kATTRACCESSOR tOPERATOR tQUOTEDMETHOD tQUOTEDIDENT
11
11
  kPREPEND kEXTENSION kINCOMPATIBLE
12
12
  type_TYPE type_SIGNATURE type_METHODTYPE tEOF
@@ -425,7 +425,12 @@ rule
425
425
  comment: leading_comment(val[0].first&.location || location))
426
426
  }
427
427
 
428
- overload: { result = nil } | kOVERLOAD
428
+ overload:
429
+ { result = nil }
430
+ | kOVERLOAD {
431
+ RBS.logger.warn "`overload def` syntax is deprecated. Use `...` syntax instead."
432
+ result = val[0]
433
+ }
429
434
 
430
435
  method_member:
431
436
  annotations attributes overload kDEF method_kind def_name method_types {
@@ -438,15 +443,24 @@ rule
438
443
  type
439
444
  end
440
445
  end
446
+
447
+ last_type = val[6].last
448
+ if last_type.is_a?(LocatedValue) && last_type.value == :dot3
449
+ overload = true
450
+ val[6].pop
451
+ else
452
+ overload = false
453
+ end
454
+
441
455
  result = Members::MethodDefinition.new(
442
456
  name: val[5].value,
443
457
  kind: val[4],
444
- types: types,
458
+ types: val[6],
445
459
  annotations: val[0],
446
460
  location: location,
447
461
  comment: leading_comment(val[0].first&.location || val[1].first&.location || val[2]&.location || val[3].location),
448
462
  attributes: val[1].map(&:value),
449
- overload: !!val[2]
463
+ overload: overload || !!val[2]
450
464
  )
451
465
  }
452
466
 
@@ -463,7 +477,7 @@ rule
463
477
 
464
478
  method_types:
465
479
  method_type { result = [val[0]] }
466
- | kSUPER { result = [LocatedValue.new(value: :super, location: val[0].location)] }
480
+ | kDOT3 { result = [LocatedValue.new(value: :dot3, location: val[0].location)] }
467
481
  | method_type kBAR method_types {
468
482
  result = val[2].unshift(val[0])
469
483
  }
@@ -548,7 +562,7 @@ rule
548
562
  kCLASS | kVOID | kNIL | kTRUE | kFALSE | kANY | kUNTYPED | kTOP | kBOT | kINSTANCE | kBOOL | kSINGLETON
549
563
  | kTYPE | kMODULE | kPRIVATE | kPUBLIC | kEND | kINCLUDE | kEXTEND | kPREPEND
550
564
  | kATTRREADER | kATTRACCESSOR | kATTRWRITER | kDEF | kEXTENSION | kSELF | kINCOMPATIBLE
551
- | kUNCHECKED | kINTERFACE | kSUPER | kALIAS | kOUT | kIN | kOVERLOAD
565
+ | kUNCHECKED | kINTERFACE | kALIAS | kOUT | kIN | kOVERLOAD
552
566
 
553
567
  module_type_params:
554
568
  { result = nil }
@@ -1218,7 +1232,6 @@ KEYWORDS = {
1218
1232
  "attr_reader" => :kATTRREADER,
1219
1233
  "attr_writer" => :kATTRWRITER,
1220
1234
  "attr_accessor" => :kATTRACCESSOR,
1221
- "super" => :kSUPER,
1222
1235
  "public" => :kPUBLIC,
1223
1236
  "private" => :kPRIVATE,
1224
1237
  "alias" => :kALIAS,
@@ -1267,6 +1280,7 @@ PUNCTS = {
1267
1280
  "!" => :kEXCLAMATION,
1268
1281
  "**" => :kSTAR2,
1269
1282
  "*" => :kSTAR,
1283
+ "..." => :kDOT3,
1270
1284
  "." => :kDOT,
1271
1285
  "<" => :kLT,
1272
1286
  "-@" => :tOPERATOR,
@@ -5,6 +5,7 @@ require "rbs/test/errors"
5
5
  require "rbs/test/type_check"
6
6
  require "rbs/test/tester"
7
7
  require "rbs/test/hook"
8
+ require "rbs/test/setup_helper"
8
9
 
9
10
  module RBS
10
11
  module Test
@@ -28,7 +28,11 @@ module RBS
28
28
  end
29
29
 
30
30
  def self.inspect_(obj)
31
- Test::INSPECT.bind(obj).call
31
+ if obj.respond_to?(:inspect)
32
+ obj.inspect
33
+ else
34
+ Test::INSPECT.bind(obj).call # For the case inspect is not defined (like BasicObject)
35
+ end
32
36
  end
33
37
 
34
38
  def self.to_string(error)
@@ -1,24 +1,29 @@
1
1
  require "rbs"
2
2
  require "rbs/test"
3
-
4
3
  require "optparse"
5
4
  require "shellwords"
6
5
 
6
+ include RBS::Test::SetupHelper
7
+
7
8
  logger = Logger.new(STDERR)
8
9
 
9
10
  begin
10
11
  opts = Shellwords.shellsplit(ENV["RBS_TEST_OPT"] || "-I sig")
11
- filter = ENV.fetch("RBS_TEST_TARGET").split(",")
12
- skips = (ENV["RBS_TEST_SKIP"] || "").split(",")
13
- sampling = !ENV.key?("RBS_TEST_NO_SAMPLE")
12
+ filter = ENV.fetch('RBS_TEST_TARGET').split(',').map! { |e| e.strip }
13
+ skips = (ENV['RBS_TEST_SKIP'] || '').split(',').map! { |e| e.strip }
14
14
  RBS.logger_level = (ENV["RBS_TEST_LOGLEVEL"] || "info")
15
- rescue
15
+ sample_size = get_sample_size(ENV['RBS_TEST_SAMPLE_SIZE'] || '')
16
+ rescue InvalidSampleSizeError => exception
17
+ RBS.logger.error exception.message
18
+ exit 1
19
+ rescue Exception => e
20
+ raise e.message
16
21
  STDERR.puts "rbs/test/setup handles the following environment variables:"
17
22
  STDERR.puts " [REQUIRED] RBS_TEST_TARGET: test target class name, `Foo::Bar,Foo::Baz` for each class or `Foo::*` for all classes under `Foo`"
18
23
  STDERR.puts " [OPTIONAL] RBS_TEST_SKIP: skip testing classes"
19
24
  STDERR.puts " [OPTIONAL] RBS_TEST_OPT: options for signatures (`-r` for libraries or `-I` for signatures)"
20
25
  STDERR.puts " [OPTIONAL] RBS_TEST_LOGLEVEL: one of debug|info|warn|error|fatal (defaults to info)"
21
- STDERR.puts " [OPTIONAL] RBS_TEST_NO_SAMPLE: if set, the type checker tests all the values of a collection"
26
+ STDERR.puts " [OPTIONAL] RBS_TEST_SAMPLE_SIZE: sets the amount of values in a collection to be type-checked (Set to `ALL` to type check all the values)"
22
27
  exit 1
23
28
  end
24
29
 
@@ -32,26 +37,38 @@ env = RBS::Environment.from_loader(loader).resolve_type_names
32
37
 
33
38
  def match(filter, name)
34
39
  if filter.end_with?("*")
35
- name.start_with?(filter[0, filter.size - 1]) || name == filter[0, filter.size-3]
40
+ size = filter.size
41
+ name.start_with?(filter[0, size - 1]) || name == filter[0, size-3]
36
42
  else
37
43
  filter == name
38
44
  end
39
45
  end
40
46
 
41
- factory = RBS::Factory.new()
47
+ def to_absolute_typename(type_name)
48
+ RBS::Factory.new().type_name(type_name).absolute!
49
+ end
50
+
42
51
  tester = RBS::Test::Tester.new(env: env)
43
52
 
44
53
  TracePoint.trace :end do |tp|
45
- class_name = tp.self.name&.yield_self {|name| factory.type_name(name).absolute! }
54
+ class_name = tp.self.name&.yield_self {|name| to_absolute_typename name }
46
55
 
47
56
  if class_name
48
- if filter.any? {|f| match(f, class_name.to_s) } && skips.none? {|f| match(f, class_name.to_s) }
57
+ if filter.any? {|f| match(to_absolute_typename(f).to_s, class_name.to_s) } && skips.none? {|f| match(f, class_name.to_s) }
49
58
  if tester.checkers.none? {|hook| hook.klass == tp.self }
50
59
  if env.class_decls.key?(class_name)
51
60
  logger.info "Setting up hooks for #{class_name}"
52
- tester.install!(tp.self, sampling: sampling)
61
+ tester.install!(tp.self, sample_size: sample_size)
53
62
  end
54
63
  end
55
64
  end
56
65
  end
57
66
  end
67
+
68
+ at_exit do
69
+ if $!.nil? || $!.is_a?(SystemExit) && $!.success?
70
+ logger.warn "No type checker was installed! " if tester.checkers.empty?
71
+ end
72
+ end
73
+
74
+
@@ -0,0 +1,29 @@
1
+ module RBS
2
+ module Test
3
+ module SetupHelper
4
+ class InvalidSampleSizeError < StandardError
5
+ attr_reader :string
6
+
7
+ def initialize(string)
8
+ @string = string
9
+ super("Sample size should be a positive integer: `#{string}`")
10
+ end
11
+ end
12
+
13
+ DEFAULT_SAMPLE_SIZE = 100
14
+
15
+ def get_sample_size(string)
16
+ case string
17
+ when ""
18
+ DEFAULT_SAMPLE_SIZE
19
+ when 'ALL'
20
+ nil
21
+ else
22
+ int_size = string.to_i
23
+ raise InvalidSampleSizeError.new(string) unless int_size.positive?
24
+ int_size
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -17,14 +17,14 @@ module RBS
17
17
  @builder ||= DefinitionBuilder.new(env: env)
18
18
  end
19
19
 
20
- def install!(klass, sampling:)
20
+ def install!(klass, sample_size:)
21
21
  RBS.logger.info { "Installing runtime type checker in #{klass}..." }
22
22
 
23
23
  type_name = factory.type_name(klass.name).absolute!
24
24
 
25
25
  builder.build_instance(type_name).tap do |definition|
26
26
  instance_key = new_key(type_name, "InstanceChecker")
27
- Observer.register(instance_key, MethodCallTester.new(klass, builder, definition, kind: :instance, sampling: sampling))
27
+ Observer.register(instance_key, MethodCallTester.new(klass, builder, definition, kind: :instance, sample_size: sample_size))
28
28
 
29
29
  definition.methods.each do |name, method|
30
30
  if method.implemented_in == type_name
@@ -36,7 +36,7 @@ module RBS
36
36
 
37
37
  builder.build_singleton(type_name).tap do |definition|
38
38
  singleton_key = new_key(type_name, "SingletonChecker")
39
- Observer.register(singleton_key, MethodCallTester.new(klass.singleton_class, builder, definition, kind: :singleton, sampling: sampling))
39
+ Observer.register(singleton_key, MethodCallTester.new(klass.singleton_class, builder, definition, kind: :singleton, sample_size: sample_size))
40
40
 
41
41
  definition.methods.each do |name, method|
42
42
  if method.implemented_in == type_name || name == :new
@@ -66,14 +66,14 @@ module RBS
66
66
  attr_reader :definition
67
67
  attr_reader :builder
68
68
  attr_reader :kind
69
- attr_reader :sampling
69
+ attr_reader :sample_size
70
70
 
71
- def initialize(self_class, builder, definition, kind:, sampling:)
71
+ def initialize(self_class, builder, definition, kind:, sample_size:)
72
72
  @self_class = self_class
73
73
  @definition = definition
74
74
  @builder = builder
75
75
  @kind = kind
76
- @sampling = sampling
76
+ @sample_size = sample_size
77
77
  end
78
78
 
79
79
  def env
@@ -81,7 +81,7 @@ module RBS
81
81
  end
82
82
 
83
83
  def check
84
- @check ||= TypeCheck.new(self_class: self_class, builder: builder, sampling: sampling)
84
+ @check ||= TypeCheck.new(self_class: self_class, builder: builder, sample_size: sample_size)
85
85
  end
86
86
 
87
87
  def format_method_name(name)
@@ -3,11 +3,14 @@ module RBS
3
3
  class TypeCheck
4
4
  attr_reader :self_class
5
5
  attr_reader :builder
6
+ attr_reader :sample_size
6
7
 
7
- def initialize(self_class:, builder:, sampling:)
8
+ DEFAULT_SAMPLE_SIZE = 100
9
+
10
+ def initialize(self_class:, builder:, sample_size:)
8
11
  @self_class = self_class
9
12
  @builder = builder
10
- @sampling = sampling
13
+ @sample_size = sample_size
11
14
  end
12
15
 
13
16
  def overloaded_call(method, method_name, call, errors:)
@@ -176,12 +179,8 @@ module RBS
176
179
  end
177
180
  end
178
181
 
179
- def sampling?
180
- !!@sampling
181
- end
182
-
183
182
  def sample(array)
184
- array.size > 100 && sampling? ? array.sample(100) : array
183
+ sample_size && (array.size > sample_size) ? array.sample(sample_size) : array
185
184
  end
186
185
 
187
186
  def value(val, type)
@@ -1,3 +1,3 @@
1
1
  module RBS
2
- VERSION = "0.7.0"
2
+ VERSION = "0.8.0"
3
3
  end
@@ -46,7 +46,7 @@ module Enumerable[unchecked out Elem, out Return]: _Each[Elem, Return]
46
46
  | () { (Elem arg0) -> untyped } -> bool
47
47
 
48
48
  def collect: [U] () { (Elem arg0) -> U } -> ::Array[U]
49
- | () -> ::Enumerator[Elem, Return]
49
+ | () -> ::Enumerator[Elem, ::Array[untyped]]
50
50
 
51
51
  def collect_concat: [U] () { (Elem arg0) -> ::Enumerator[U, untyped] } -> ::Array[U]
52
52
 
@@ -317,7 +317,7 @@ module Enumerable[unchecked out Elem, out Return]: _Each[Elem, Return]
317
317
  | () -> ::Enumerator[Elem, Return]
318
318
 
319
319
  def map: [U] () { (Elem arg0) -> U } -> ::Array[U]
320
- | () -> ::Enumerator[Elem, Return]
320
+ | () -> ::Enumerator[Elem, ::Array[untyped]]
321
321
 
322
322
  def member?: (untyped arg0) -> bool
323
323
 
@@ -0,0 +1,159 @@
1
+ # Creates and manages pseudo terminals (PTYs). See also
2
+ # http://en.wikipedia.org/wiki/Pseudo_terminal
3
+ #
4
+ # PTY allows you to allocate new terminals using ::open or ::spawn a new
5
+ # terminal with a specific command.
6
+ #
7
+ # ## Example
8
+ #
9
+ # In this example we will change the buffering type in the `factor` command,
10
+ # assuming that factor uses stdio for stdout buffering.
11
+ #
12
+ # If IO.pipe is used instead of PTY.open, this code deadlocks because factor's
13
+ # stdout is fully buffered.
14
+ #
15
+ # # start by requiring the standard library PTY
16
+ # require 'pty'
17
+ #
18
+ # master, slave = PTY.open
19
+ # read, write = IO.pipe
20
+ # pid = spawn("factor", :in=>read, :out=>slave)
21
+ # read.close # we dont need the read
22
+ # slave.close # or the slave
23
+ #
24
+ # # pipe "42" to the factor command
25
+ # write.puts "42"
26
+ # # output the response from factor
27
+ # p master.gets #=> "42: 2 3 7\n"
28
+ #
29
+ # # pipe "144" to factor and print out the response
30
+ # write.puts "144"
31
+ # p master.gets #=> "144: 2 2 2 2 3 3\n"
32
+ # write.close # close the pipe
33
+ #
34
+ # # The result of read operation when pty slave is closed is platform
35
+ # # dependent.
36
+ # ret = begin
37
+ # master.gets # FreeBSD returns nil.
38
+ # rescue Errno::EIO # GNU/Linux raises EIO.
39
+ # nil
40
+ # end
41
+ # p ret #=> nil
42
+ #
43
+ # ## License
44
+ #
45
+ # C) Copyright 1998 by Akinori Ito.
46
+ #
47
+ # This software may be redistributed freely for this purpose, in full
48
+ # or in part, provided that this entire copyright notice is included
49
+ # on any copies of this software and applications and derivations thereof.
50
+ #
51
+ # This software is provided on an "as is" basis, without warranty of any
52
+ # kind, either expressed or implied, as to any matter including, but not
53
+ # limited to warranty of fitness of purpose, or merchantability, or
54
+ # results obtained from use of this software.
55
+ #
56
+ module PTY
57
+ # Checks the status of the child process specified by `pid`. Returns `nil` if
58
+ # the process is still alive.
59
+ #
60
+ # If the process is not alive, and `raise` was true, a PTY::ChildExited
61
+ # exception will be raised. Otherwise it will return a Process::Status instance.
62
+ #
63
+ # `pid`
64
+ # : The process id of the process to check
65
+ # `raise`
66
+ # : If `true` and the process identified by `pid` is no longer alive a
67
+ # PTY::ChildExited is raised.
68
+ def self.check: (Integer pid) -> (Process::Status | nil)
69
+ | (Integer pid, FalseClass raise) -> (Process::Status | nil)
70
+ | (Integer pid, TrueClass raise) -> nil
71
+
72
+ # Spawns the specified command on a newly allocated pty. You can also use the
73
+ # alias ::getpty.
74
+ #
75
+ # The command's controlling tty is set to the slave device of the pty and its
76
+ # standard input/output/error is redirected to the slave device.
77
+ #
78
+ # `command` and `command_line` are the full commands to run, given a String. Any
79
+ # additional `arguments` will be passed to the command.
80
+ #
81
+ # ### Return values
82
+ #
83
+ # In the non-block form this returns an array of size three, `[r, w, pid]`.
84
+ #
85
+ # In the block form these same values will be yielded to the block:
86
+ #
87
+ # `r`
88
+ # : A readable IO that contains the command's standard output and standard
89
+ # error
90
+ # `w`
91
+ # : A writable IO that is the command's standard input
92
+ # `pid`
93
+ # : The process identifier for the command.
94
+ def self.getpty: (*String command) -> [ IO, IO, Integer ]
95
+ | (*String command) { ([ IO ,IO , Integer ]) -> untyped } -> untyped
96
+
97
+ # Allocates a pty (pseudo-terminal).
98
+ #
99
+ # In the block form, yields two arguments `master_io, slave_file` and the value
100
+ # of the block is returned from `open`.
101
+ #
102
+ # The IO and File are both closed after the block completes if they haven't been
103
+ # already closed.
104
+ #
105
+ # PTY.open {|master, slave|
106
+ # p master #=> #<IO:masterpty:/dev/pts/1>
107
+ # p slave #=> #<File:/dev/pts/1>
108
+ # p slave.path #=> "/dev/pts/1"
109
+ # }
110
+ #
111
+ # In the non-block form, returns a two element array, `[master_io, slave_file]`.
112
+ #
113
+ # master, slave = PTY.open
114
+ # # do something with master for IO, or the slave file
115
+ #
116
+ # The arguments in both forms are:
117
+ #
118
+ # `master_io`
119
+ # : the master of the pty, as an IO.
120
+ # `slave_file`
121
+ # : the slave of the pty, as a File. The path to the terminal device is
122
+ # available via `slave_file.path`
123
+ #
124
+ #
125
+ # IO#raw! is usable to disable newline conversions:
126
+ #
127
+ # require 'io/console'
128
+ # PTY.open {|m, s|
129
+ # s.raw!
130
+ # ...
131
+ # }
132
+ def self.open: () -> [ IO, File ]
133
+ | () { ([ IO , File ]) -> untyped } -> untyped
134
+
135
+ # Spawns the specified command on a newly allocated pty. You can also use the
136
+ # alias ::getpty.
137
+ #
138
+ # The command's controlling tty is set to the slave device of the pty and its
139
+ # standard input/output/error is redirected to the slave device.
140
+ #
141
+ # `command` and `command_line` are the full commands to run, given a String. Any
142
+ # additional `arguments` will be passed to the command.
143
+ #
144
+ # ### Return values
145
+ #
146
+ # In the non-block form this returns an array of size three, `[r, w, pid]`.
147
+ #
148
+ # In the block form these same values will be yielded to the block:
149
+ #
150
+ # `r`
151
+ # : A readable IO that contains the command's standard output and standard
152
+ # error
153
+ # `w`
154
+ # : A writable IO that is the command's standard input
155
+ # `pid`
156
+ # : The process identifier for the command.
157
+ def self.spawn: (*String command) -> [ IO, IO, Integer ]
158
+ | (*String command) {([ IO , IO , Integer ]) -> untyped } -> untyped
159
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.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: 2020-07-20 00:00:00.000000000 Z
11
+ date: 2020-08-01 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: RBS is the language for type signatures for Ruby and standard library
14
14
  definitions.
@@ -73,6 +73,7 @@ files:
73
73
  - lib/rbs/test/hook.rb
74
74
  - lib/rbs/test/observer.rb
75
75
  - lib/rbs/test/setup.rb
76
+ - lib/rbs/test/setup_helper.rb
76
77
  - lib/rbs/test/spy.rb
77
78
  - lib/rbs/test/tester.rb
78
79
  - lib/rbs/test/type_check.rb
@@ -169,6 +170,7 @@ files:
169
170
  - stdlib/pathname/pathname.rbs
170
171
  - stdlib/prime/integer-extension.rbs
171
172
  - stdlib/prime/prime.rbs
173
+ - stdlib/pty/pty.rbs
172
174
  - stdlib/securerandom/securerandom.rbs
173
175
  - stdlib/set/set.rbs
174
176
  - stdlib/tmpdir/tmpdir.rbs