rbs 3.3.2 → 3.4.0

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 (132) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/comments.yml +2 -5
  3. data/.github/workflows/ruby.yml +7 -8
  4. data/.github/workflows/typecheck.yml +37 -0
  5. data/CHANGELOG.md +65 -0
  6. data/Gemfile +1 -1
  7. data/Gemfile.lock +11 -11
  8. data/README.md +1 -0
  9. data/Rakefile +2 -2
  10. data/Steepfile +2 -2
  11. data/core/array.rbs +19 -49
  12. data/core/basic_object.rbs +2 -2
  13. data/core/comparable.rbs +17 -8
  14. data/core/complex.rbs +82 -43
  15. data/core/data.rbs +2 -4
  16. data/core/dir.rbs +635 -295
  17. data/core/enumerable.rbs +11 -18
  18. data/core/enumerator.rbs +37 -31
  19. data/core/errors.rbs +4 -0
  20. data/core/false_class.rbs +34 -15
  21. data/core/fiber.rbs +23 -0
  22. data/core/file.rbs +329 -120
  23. data/core/float.rbs +17 -32
  24. data/core/gc.rbs +17 -11
  25. data/core/hash.rbs +22 -44
  26. data/core/integer.rbs +82 -113
  27. data/core/io/buffer.rbs +90 -47
  28. data/core/io.rbs +54 -121
  29. data/core/kernel.rbs +442 -489
  30. data/core/match_data.rbs +55 -56
  31. data/core/module.rbs +45 -1
  32. data/core/nil_class.rbs +98 -35
  33. data/core/numeric.rbs +22 -32
  34. data/core/object_space/weak_key_map.rbs +102 -0
  35. data/core/process.rbs +1242 -655
  36. data/core/ractor.rbs +139 -120
  37. data/core/range.rbs +100 -4
  38. data/core/rational.rbs +0 -4
  39. data/core/rbs/unnamed/argf.rbs +16 -8
  40. data/core/rbs/unnamed/env_class.rbs +0 -24
  41. data/core/refinement.rbs +8 -0
  42. data/core/regexp.rbs +1149 -598
  43. data/core/ruby_vm.rbs +126 -12
  44. data/core/rubygems/platform.rbs +9 -0
  45. data/core/rubygems/rubygems.rbs +1 -1
  46. data/core/rubygems/version.rbs +5 -1
  47. data/core/set.rbs +20 -22
  48. data/core/signal.rbs +4 -4
  49. data/core/string.rbs +283 -230
  50. data/core/string_io.rbs +2 -14
  51. data/core/struct.rbs +404 -24
  52. data/core/symbol.rbs +1 -19
  53. data/core/thread.rbs +29 -12
  54. data/core/time.rbs +227 -104
  55. data/core/trace_point.rbs +2 -5
  56. data/core/true_class.rbs +54 -21
  57. data/core/warning.rbs +14 -11
  58. data/docs/data_and_struct.md +29 -0
  59. data/docs/gem.md +58 -0
  60. data/docs/syntax.md +3 -5
  61. data/docs/tools.md +1 -0
  62. data/ext/rbs_extension/lexer.c +643 -559
  63. data/ext/rbs_extension/lexer.re +5 -1
  64. data/ext/rbs_extension/parser.c +12 -3
  65. data/ext/rbs_extension/unescape.c +7 -47
  66. data/lib/rbs/cli/diff.rb +4 -1
  67. data/lib/rbs/cli/validate.rb +280 -0
  68. data/lib/rbs/cli.rb +2 -194
  69. data/lib/rbs/collection/config.rb +5 -6
  70. data/lib/rbs/collection/sources/git.rb +1 -1
  71. data/lib/rbs/collection.rb +1 -0
  72. data/lib/rbs/diff.rb +7 -4
  73. data/lib/rbs/errors.rb +11 -0
  74. data/lib/rbs/test/errors.rb +10 -2
  75. data/lib/rbs/test/guaranteed.rb +2 -3
  76. data/lib/rbs/test/type_check.rb +15 -10
  77. data/lib/rbs/test.rb +3 -3
  78. data/lib/rbs/types.rb +29 -0
  79. data/lib/rbs/unit_test/convertibles.rb +176 -0
  80. data/lib/rbs/unit_test/spy.rb +136 -0
  81. data/lib/rbs/unit_test/type_assertions.rb +341 -0
  82. data/lib/rbs/unit_test/with_aliases.rb +143 -0
  83. data/lib/rbs/unit_test.rb +6 -0
  84. data/lib/rbs/version.rb +1 -1
  85. data/sig/cli/validate.rbs +43 -0
  86. data/sig/diff.rbs +3 -1
  87. data/sig/errors.rbs +8 -0
  88. data/sig/rbs.rbs +1 -1
  89. data/sig/test/errors.rbs +52 -0
  90. data/sig/test/guranteed.rbs +9 -0
  91. data/sig/test/type_check.rbs +19 -0
  92. data/sig/test.rbs +82 -0
  93. data/sig/types.rbs +6 -1
  94. data/sig/unit_test/convertibles.rbs +154 -0
  95. data/sig/unit_test/spy.rbs +28 -0
  96. data/sig/unit_test/type_assertions.rbs +194 -0
  97. data/sig/unit_test/with_aliases.rbs +136 -0
  98. data/stdlib/base64/0/base64.rbs +307 -45
  99. data/stdlib/bigdecimal/0/big_decimal.rbs +35 -15
  100. data/stdlib/coverage/0/coverage.rbs +2 -2
  101. data/stdlib/csv/0/csv.rbs +25 -55
  102. data/stdlib/date/0/date.rbs +1 -43
  103. data/stdlib/date/0/date_time.rbs +1 -13
  104. data/stdlib/delegate/0/delegator.rbs +186 -0
  105. data/stdlib/delegate/0/kernel.rbs +47 -0
  106. data/stdlib/delegate/0/simple_delegator.rbs +98 -0
  107. data/stdlib/did_you_mean/0/did_you_mean.rbs +1 -1
  108. data/stdlib/erb/0/erb.rbs +2 -2
  109. data/stdlib/fileutils/0/fileutils.rbs +0 -19
  110. data/stdlib/io-console/0/io-console.rbs +12 -1
  111. data/stdlib/ipaddr/0/ipaddr.rbs +2 -1
  112. data/stdlib/json/0/json.rbs +320 -81
  113. data/stdlib/logger/0/logger.rbs +9 -5
  114. data/stdlib/minitest/0/minitest/test/lifecycle_hooks.rbs +6 -6
  115. data/stdlib/monitor/0/monitor.rbs +78 -0
  116. data/stdlib/net-http/0/net-http.rbs +1880 -543
  117. data/stdlib/objspace/0/objspace.rbs +19 -13
  118. data/stdlib/openssl/0/openssl.rbs +508 -127
  119. data/stdlib/optparse/0/optparse.rbs +25 -11
  120. data/stdlib/pathname/0/pathname.rbs +1 -1
  121. data/stdlib/pp/0/pp.rbs +2 -5
  122. data/stdlib/prettyprint/0/prettyprint.rbs +2 -2
  123. data/stdlib/pstore/0/pstore.rbs +2 -4
  124. data/stdlib/rdoc/0/comment.rbs +1 -2
  125. data/stdlib/resolv/0/resolv.rbs +4 -2
  126. data/stdlib/socket/0/socket.rbs +2 -2
  127. data/stdlib/socket/0/unix_socket.rbs +2 -2
  128. data/stdlib/strscan/0/string_scanner.rbs +3 -2
  129. data/stdlib/tempfile/0/tempfile.rbs +1 -1
  130. data/stdlib/uri/0/common.rbs +245 -123
  131. metadata +24 -4
  132. data/lib/rbs/test/spy.rb +0 -6
data/lib/rbs/diff.rb CHANGED
@@ -2,11 +2,12 @@
2
2
 
3
3
  module RBS
4
4
  class Diff
5
- def initialize(type_name:, library_options:, after_path: [], before_path: [])
5
+ def initialize(type_name:, library_options:, after_path: [], before_path: [], detail: false)
6
6
  @type_name = type_name
7
7
  @library_options = library_options
8
8
  @after_path = after_path
9
9
  @before_path = before_path
10
+ @detail = detail
10
11
  end
11
12
 
12
13
  def each_diff(&block)
@@ -100,11 +101,12 @@ module RBS
100
101
  if definition_method
101
102
  prefix = kind == :instance ? "" : "self."
102
103
 
104
+ detail_to_s = @detail ? "[#{definition_method.defined_in} #{definition_method.accessibility}] " : ""
103
105
  if definition_method.alias_of
104
106
  first_def = definition_method.alias_of.defs.first #: Definition::Method::TypeDef
105
- "alias #{prefix}#{key} #{prefix}#{first_def.member.name}"
107
+ "#{detail_to_s}alias #{prefix}#{key} #{prefix}#{first_def.member.name}"
106
108
  else
107
- "def #{prefix}#{key}: #{definition_method.method_types.join(" | ")}"
109
+ "#{detail_to_s}def #{prefix}#{key}: #{definition_method.method_types.join(" | ")}"
108
110
  end
109
111
  else
110
112
  +"-"
@@ -113,7 +115,8 @@ module RBS
113
115
 
114
116
  def constant_to_s(constant)
115
117
  if constant
116
- "#{constant.name.name}: #{constant.type}"
118
+ detail_to_s = @detail ? "[#{constant.name.namespace.to_type_name.to_s}] " : ""
119
+ "#{detail_to_s}#{constant.name.name}: #{constant.type}"
117
120
  else
118
121
  +"-"
119
122
  end
data/lib/rbs/errors.rb CHANGED
@@ -557,4 +557,15 @@ module RBS
557
557
  @alias_entry.decl.location
558
558
  end
559
559
  end
560
+
561
+ class WillSyntaxError < DefinitionError
562
+ include DetailedMessageable
563
+
564
+ attr_reader :location
565
+
566
+ def initialize(message, location:)
567
+ super "#{Location.to_string(location)}: #{message}"
568
+ @location = location
569
+ end
570
+ end
560
571
  end
@@ -29,8 +29,11 @@ module RBS
29
29
  end
30
30
  end
31
31
 
32
+ RESPOND_TO = ::Kernel.instance_method :respond_to?
33
+ private_constant :RESPOND_TO
34
+
32
35
  def self.inspect_(obj)
33
- if obj.respond_to?(:inspect)
36
+ if RESPOND_TO.bind_call(obj, :inspect)
34
37
  obj.inspect
35
38
  else
36
39
  Test::INSPECT.bind(obj).call # For the case inspect is not defined (like BasicObject)
@@ -38,7 +41,12 @@ module RBS
38
41
  end
39
42
 
40
43
  def self.to_string(error)
41
- method = "#{error.klass.name}#{error.method_name}"
44
+ name = if error.klass.singleton_class?
45
+ inspect_(error.klass).sub(/\A#<Class:(.*)>\z/, '\1')
46
+ else
47
+ error.klass.name
48
+ end
49
+ method = "#{name}#{error.method_name}"
42
50
  case error
43
51
  when ArgumentTypeError
44
52
  "[#{method}] ArgumentTypeError: expected #{format_param error.param} but given `#{inspect_(error.value)}`"
@@ -10,8 +10,7 @@ module RBS
10
10
 
11
11
  module_function def guaranteed_inspect(obj)
12
12
  obj.inspect
13
- rescue NoMethodError => err
14
- raise unless err.name == :inspect && EQUAL.bind_call(obj, err.receiver)
13
+ rescue NoMethodError
15
14
  INSPECT.bind_call(obj)
16
15
  end
17
16
 
@@ -20,7 +19,7 @@ module RBS
20
19
 
21
20
  instance_variables.each_with_index do |variable, index|
22
21
  string.concat ', ' unless index.zero?
23
- string.concat "#{variable}: #{guaranteed_inspect(variable)}"
22
+ string.concat "#{variable}: #{guaranteed_inspect(instance_variable_get(variable))}"
24
23
  end
25
24
 
26
25
  string.concat '>'
@@ -10,8 +10,6 @@ module RBS
10
10
  attr_reader :instance_class
11
11
  attr_reader :class_class
12
12
 
13
- attr_reader :const_cache
14
-
15
13
  DEFAULT_SAMPLE_SIZE = 100
16
14
 
17
15
  def initialize(self_class:, builder:, sample_size:, unchecked_classes:, instance_class: Object, class_class: Module)
@@ -21,7 +19,6 @@ module RBS
21
19
  @builder = builder
22
20
  @sample_size = sample_size
23
21
  @unchecked_classes = unchecked_classes.uniq
24
- @const_cache = {}
25
22
  end
26
23
 
27
24
  def overloaded_call(method, method_name, call, errors:)
@@ -38,6 +35,17 @@ module RBS
38
35
  if es.size == 1
39
36
  errors.push(*es[0])
40
37
  else
38
+ RBS.logger.warn do
39
+ message = +"[#{self_class}#{method_name}] UnresolvedOverloadingError "
40
+ message << method.method_types.zip(es).map do |method_type, es|
41
+ msg = +"method_type=`#{method_type}`"
42
+ details = es.map do |e|
43
+ "\"#{Errors.to_string(e).sub("[#{e.klass.name}#{e.method_name}] ", "") }\""
44
+ end.join(', ')
45
+ msg << " details=[#{details}]"
46
+ end.join(', ')
47
+ message
48
+ end
41
49
  errors << Errors::UnresolvedOverloadingError.new(
42
50
  klass: self_class,
43
51
  method_name: method_name,
@@ -208,11 +216,9 @@ module RBS
208
216
  end
209
217
 
210
218
  def get_class(type_name)
211
- const_cache[type_name] ||= begin
212
- Object.const_get(type_name.to_s)
213
- rescue NameError
214
- nil
215
- end
219
+ Object.const_get(type_name.to_s)
220
+ rescue NameError
221
+ nil
216
222
  end
217
223
 
218
224
  def is_double?(value)
@@ -301,10 +307,9 @@ module RBS
301
307
  end
302
308
  val.is_a?(singleton_class)
303
309
  when Types::Interface
304
- methods = Set.new(Test.call(val, METHODS))
305
310
  if (definition = builder.build_interface(type.name.absolute!))
306
311
  definition.methods.each_key.all? do |method_name|
307
- methods.member?(method_name)
312
+ Test.call(val, RESPOND_TOP, method_name)
308
313
  end
309
314
  end
310
315
  when Types::Variable
data/lib/rbs/test.rb CHANGED
@@ -3,7 +3,6 @@
3
3
  require "securerandom"
4
4
  require "rbs/test/guaranteed"
5
5
  require "rbs/test/observer"
6
- require "rbs/test/spy"
7
6
  require "rbs/test/errors"
8
7
  require "rbs/test/type_check"
9
8
  require "rbs/test/tester"
@@ -22,6 +21,7 @@ module RBS
22
21
  PP = Kernel.instance_method(:pp)
23
22
  INSPECT = Kernel.instance_method(:inspect)
24
23
  METHODS = Kernel.instance_method(:methods)
24
+ RESPOND_TOP = Kernel.instance_method(:respond_to?)
25
25
 
26
26
  class ArgumentsReturn
27
27
  include Guaranteed::Inspect
@@ -85,11 +85,11 @@ module RBS
85
85
 
86
86
  if ::UnboundMethod.instance_methods.include?(:bind_call)
87
87
  def self.call(receiver, method, *args, &block)
88
- method.bind_call(receiver, *args, &block)
88
+ __skip__ = method.bind_call(receiver, *args, &block)
89
89
  end
90
90
  else
91
91
  def self.call(receiver, method, *args, &block)
92
- method.bind(receiver).call(*args, &block)
92
+ __skip__ = method.bind(receiver).call(*args, &block)
93
93
  end
94
94
  end
95
95
  end
data/lib/rbs/types.rb CHANGED
@@ -1399,6 +1399,35 @@ module RBS
1399
1399
  def with_nonreturn_void?
1400
1400
  false
1401
1401
  end
1402
+
1403
+ TABLE = {
1404
+ "\\a" => "\a",
1405
+ "\\b" => "\b",
1406
+ "\\e" => "\033",
1407
+ "\\f" => "\f",
1408
+ "\\n" => "\n",
1409
+ "\\r" => "\r",
1410
+ "\\s" => " ",
1411
+ "\\t" => "\t",
1412
+ "\\v" => "\v",
1413
+ "\\\"" => "\"",
1414
+ "\\\'" => "'",
1415
+ "\\\\" => "\\",
1416
+ "\\" => ""
1417
+ }
1418
+
1419
+ def self.unescape_string(string, is_double_quote)
1420
+ if is_double_quote
1421
+ string.gsub!(/\\([0-9]{1,3})/) { ($1 || "").to_i(8).chr }
1422
+ string.gsub!(/\\x([0-9a-f]{1,2})/) { ($1 || "").to_i(16).chr }
1423
+ string.gsub!(/\\u([0-9a-fA-F]{4})/) { ($1 || "").to_i(16).chr(Encoding::UTF_8) }
1424
+ string.gsub!(/\\[abefnrstv"'\\]?/, TABLE)
1425
+ string
1426
+ else
1427
+ string.gsub!(/\\['\\]/, TABLE)
1428
+ string
1429
+ end
1430
+ end
1402
1431
  end
1403
1432
  end
1404
1433
  end
@@ -0,0 +1,176 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBS
4
+ module UnitTest
5
+ module Convertibles
6
+ class BlankSlate < BasicObject
7
+ instance_methods.each do |im|
8
+ next if im == :__send__
9
+ undef_method im
10
+ end
11
+
12
+ def __with_object_methods(*methods)
13
+ methods.each do |method|
14
+ singleton_class = ::Object.instance_method(:singleton_class).bind_call(self) #: Class
15
+ singleton_class.instance_eval do
16
+ define_method method, ::Object.instance_method(method)
17
+ end
18
+ end
19
+ self
20
+ end
21
+ end
22
+
23
+ class ToIO < BlankSlate
24
+ def initialize(io = $stdout)
25
+ @io = io
26
+ end
27
+
28
+ def to_io
29
+ @io
30
+ end
31
+ end
32
+
33
+ class ToI < BlankSlate
34
+ def initialize(value = 3)
35
+ @value = value
36
+ end
37
+
38
+ def to_i
39
+ @value
40
+ end
41
+ end
42
+
43
+ class ToInt < BlankSlate
44
+ def initialize(value = 3)
45
+ @value = value
46
+ end
47
+
48
+ def to_int
49
+ @value
50
+ end
51
+ end
52
+
53
+ class ToF < BlankSlate
54
+ def initialize(value = 0.1)
55
+ @value = value
56
+ end
57
+
58
+ def to_f
59
+ @value
60
+ end
61
+ end
62
+
63
+ class ToR < BlankSlate
64
+ def initialize(value = 1r)
65
+ @value = value
66
+ end
67
+
68
+ def to_r
69
+ @value
70
+ end
71
+ end
72
+
73
+ class ToC < BlankSlate
74
+ def initialize(value = 1i)
75
+ @value = value
76
+ end
77
+
78
+ def to_c
79
+ @value
80
+ end
81
+ end
82
+
83
+ class ToStr < BlankSlate
84
+ def initialize(value = "")
85
+ @value = value
86
+ end
87
+
88
+ def to_str
89
+ @value
90
+ end
91
+ end
92
+
93
+ class ToS < BlankSlate
94
+ def initialize(value = "")
95
+ @value = value
96
+ end
97
+
98
+ def to_s
99
+ @value
100
+ end
101
+ end
102
+
103
+ class ToSym < BlankSlate
104
+ def initialize(value = :&)
105
+ @value = value
106
+ end
107
+
108
+ def to_sym
109
+ @value
110
+ end
111
+ end
112
+
113
+ class ToA < BlankSlate
114
+ def initialize(*args)
115
+ @args = args
116
+ end
117
+
118
+ def to_a
119
+ @args
120
+ end
121
+ end
122
+
123
+ class ToArray < BlankSlate
124
+ def initialize(*args)
125
+ @args = args
126
+ end
127
+
128
+ def to_ary
129
+ @args
130
+ end
131
+ end
132
+
133
+ class ToHash < BlankSlate
134
+ def initialize(hash = { 'hello' => 'world' })
135
+ @hash = hash
136
+ end
137
+
138
+ def to_hash
139
+ @hash
140
+ end
141
+ end
142
+
143
+ class ToPath < BlankSlate
144
+ def initialize(value = "")
145
+ @value = value
146
+ end
147
+
148
+ def to_path
149
+ @value
150
+ end
151
+ end
152
+
153
+ class CustomRange < BlankSlate
154
+ attr_reader :begin, :end
155
+
156
+ def initialize(begin_, end_, exclude_end = false)
157
+ @begin = begin_
158
+ @end = end_
159
+ @exclude_end = exclude_end
160
+ end
161
+
162
+ def exclude_end? = @exclude_end
163
+ end
164
+
165
+ class Each < BlankSlate
166
+ def initialize(*args)
167
+ @args = args
168
+ end
169
+
170
+ def each(&block)
171
+ @args.each(&block)
172
+ end
173
+ end
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,136 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBS
4
+ module UnitTest
5
+ module Spy
6
+ def self.wrap(object, method_name)
7
+ spy = WrapSpy.new(object: object, method_name: method_name)
8
+
9
+ if block_given?
10
+ begin
11
+ yield spy, spy.wrapped_object
12
+ end
13
+ else
14
+ spy
15
+ end
16
+ end
17
+
18
+ class WrapSpy
19
+ attr_accessor :callback
20
+ attr_reader :object
21
+ attr_reader :method_name
22
+
23
+ def initialize(object:, method_name:)
24
+ @callback = -> (_) { }
25
+ @object = object
26
+ @method_name = method_name
27
+ end
28
+
29
+ def wrapped_object
30
+ spy = self #: WrapSpy[untyped]
31
+
32
+ Class.new(BasicObject) do
33
+ # @type self: Class
34
+
35
+ define_method(:method_missing) do |name, *args, &block|
36
+ spy.object.__send__(name, *args, &block)
37
+ end
38
+
39
+ define_method(
40
+ spy.method_name,
41
+ _ = -> (*args, &block) do
42
+ return_value = nil
43
+ exception = nil
44
+ block_calls = [] #: Array[Test::ArgumentsReturn]
45
+
46
+ spy_block = if block
47
+ Object.new.instance_eval do |fresh|
48
+ proc = -> (*block_args) do
49
+ block_exn = nil
50
+ block_return = nil
51
+
52
+ begin
53
+ block_return = if self.equal?(fresh)
54
+ # no instance eval
55
+ block.call(*block_args)
56
+ else
57
+ self.instance_exec(*block_args, &block)
58
+ end
59
+ rescue Exception => exn
60
+ block_exn = exn
61
+ end
62
+
63
+ if block_exn
64
+ block_calls << Test::ArgumentsReturn.exception(
65
+ arguments: block_args,
66
+ exception: block_exn
67
+ )
68
+ else
69
+ block_calls << Test::ArgumentsReturn.return(
70
+ arguments: block_args,
71
+ value: block_return
72
+ )
73
+ end
74
+
75
+ if block_exn
76
+ raise block_exn
77
+ else
78
+ block_return
79
+ end
80
+ end #: Proc
81
+
82
+ proc.ruby2_keywords
83
+ end
84
+ end
85
+
86
+ begin
87
+ if spy_block
88
+ return_value = spy.object.__send__(spy.method_name, *args) do |*a, **k, &b|
89
+ spy_block.call(*a, **k, &b)
90
+ end
91
+ else
92
+ return_value = spy.object.__send__(spy.method_name, *args, &spy_block)
93
+ end
94
+ rescue ::Exception => exn
95
+ exception = exn
96
+ end
97
+
98
+ return_value
99
+
100
+ ensure
101
+ call =
102
+ case
103
+ when exception
104
+ Test::ArgumentsReturn.exception(
105
+ arguments: args,
106
+ exception: exception
107
+ )
108
+ when return_value
109
+ Test::ArgumentsReturn.return(
110
+ arguments: args,
111
+ value: return_value
112
+ )
113
+ else
114
+ # break
115
+ Test::ArgumentsReturn.break(arguments: args)
116
+ end
117
+ trace = RBS::Test::CallTrace.new(
118
+ method_name: spy.method_name,
119
+ method_call: call,
120
+ block_calls: block_calls,
121
+ block_given: block != nil
122
+ )
123
+
124
+ spy.callback.call(trace)
125
+
126
+ if exception
127
+ spy.object.__send__(:raise, exception)
128
+ end
129
+ end.ruby2_keywords
130
+ )
131
+ end.new()
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end