rbs 0.20.1 → 1.0.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/Rakefile +4 -0
- data/core/builtin.rbs +4 -0
- data/core/io.rbs +159 -6
- data/core/kernel.rbs +1 -1
- data/goodcheck.yml +20 -0
- data/lib/rbs.rb +2 -0
- data/lib/rbs/ast/declarations.rb +7 -2
- data/lib/rbs/ast/members.rb +1 -1
- data/lib/rbs/cli.rb +10 -10
- data/lib/rbs/definition.rb +70 -3
- data/lib/rbs/definition_builder.rb +542 -1006
- data/lib/rbs/definition_builder/ancestor_builder.rb +476 -0
- data/lib/rbs/definition_builder/method_builder.rb +217 -0
- data/lib/rbs/environment.rb +2 -1
- data/lib/rbs/errors.rb +71 -66
- data/lib/rbs/parser.rb +673 -627
- data/lib/rbs/parser.y +13 -2
- data/lib/rbs/prototype/rb.rb +1 -1
- data/lib/rbs/prototype/rbi.rb +1 -1
- data/lib/rbs/prototype/runtime.rb +52 -32
- data/lib/rbs/substitution.rb +4 -0
- data/lib/rbs/test.rb +3 -1
- data/lib/rbs/test/hook.rb +20 -6
- data/lib/rbs/validator.rb +4 -2
- data/lib/rbs/variance_calculator.rb +5 -1
- data/lib/rbs/version.rb +1 -1
- data/sig/definition.rbs +6 -1
- data/sig/errors.rbs +20 -0
- data/sig/type_name_resolver.rbs +4 -2
- data/sig/validator.rbs +12 -0
- data/stdlib/logger/0/log_device.rbs +1 -2
- data/stdlib/time/0/time.rbs +327 -0
- data/stdlib/uri/0/common.rbs +401 -0
- data/stdlib/uri/0/rfc2396_parser.rbs +9 -0
- data/stdlib/uri/0/rfc3986_parser.rbs +2 -0
- data/steep/Gemfile.lock +10 -11
- metadata +13 -5
data/lib/rbs/parser.y
CHANGED
@@ -99,11 +99,13 @@ rule
|
|
99
99
|
{ result = nil }
|
100
100
|
| kLT class_name {
|
101
101
|
result = Declarations::Class::Super.new(name: val[1].value,
|
102
|
-
args: []
|
102
|
+
args: [],
|
103
|
+
location: val[1].location)
|
103
104
|
}
|
104
105
|
| kLT class_name kLBRACKET type_list kRBRACKET {
|
105
106
|
result = Declarations::Class::Super.new(name: val[1].value,
|
106
|
-
args: val[3]
|
107
|
+
args: val[3],
|
108
|
+
location: val[1].location + val[4].location)
|
107
109
|
}
|
108
110
|
|
109
111
|
module_decl:
|
@@ -839,6 +841,15 @@ rule
|
|
839
841
|
| keyword type {
|
840
842
|
result = { val[0].value => val[1] }
|
841
843
|
}
|
844
|
+
| identifier_keywords kCOLON type {
|
845
|
+
result = { val[0].value => val[2] }
|
846
|
+
}
|
847
|
+
| tQUOTEDIDENT kCOLON type {
|
848
|
+
result = { val[0].value => val[2] }
|
849
|
+
}
|
850
|
+
| tQUOTEDMETHOD kCOLON type {
|
851
|
+
result = { val[0].value => val[2] }
|
852
|
+
}
|
842
853
|
|
843
854
|
keyword_name:
|
844
855
|
keyword
|
data/lib/rbs/prototype/rb.rb
CHANGED
@@ -85,7 +85,7 @@ module RBS
|
|
85
85
|
class_name, super_class, *class_body = node.children
|
86
86
|
kls = AST::Declarations::Class.new(
|
87
87
|
name: const_to_name(class_name),
|
88
|
-
super_class: super_class && AST::Declarations::Class::Super.new(name: const_to_name(super_class), args: []),
|
88
|
+
super_class: super_class && AST::Declarations::Class::Super.new(name: const_to_name(super_class), args: [], location: nil),
|
89
89
|
type_params: AST::Declarations::ModuleTypeParams.empty,
|
90
90
|
members: [],
|
91
91
|
annotations: [],
|
data/lib/rbs/prototype/rbi.rb
CHANGED
@@ -47,7 +47,7 @@ module RBS
|
|
47
47
|
def push_class(name, super_class, comment:)
|
48
48
|
modules.push AST::Declarations::Class.new(
|
49
49
|
name: nested_name(name),
|
50
|
-
super_class: super_class && AST::Declarations::Class::Super.new(name: const_to_name(super_class), args: []),
|
50
|
+
super_class: super_class && AST::Declarations::Class::Super.new(name: const_to_name(super_class), args: [], location: nil),
|
51
51
|
type_params: AST::Declarations::ModuleTypeParams.empty,
|
52
52
|
members: [],
|
53
53
|
annotations: [],
|
@@ -61,11 +61,32 @@ module RBS
|
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
|
-
def
|
65
|
-
supers = Set
|
66
|
-
|
64
|
+
def each_included_module(type_name, mod)
|
65
|
+
supers = Set[]
|
66
|
+
|
67
|
+
mod.included_modules.each do |mix|
|
68
|
+
supers.merge(mix.included_modules)
|
69
|
+
end
|
70
|
+
|
71
|
+
if mod.is_a?(Class)
|
72
|
+
mod.superclass.included_modules.each do |mix|
|
73
|
+
supers << mix
|
74
|
+
supers.merge(mix.included_modules)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
mod.included_modules.each do |mix|
|
67
79
|
unless supers.include?(mix)
|
68
|
-
|
80
|
+
unless const_name(mix)
|
81
|
+
RBS.logger.warn("Skipping anonymous module #{mix} included in #{mod}")
|
82
|
+
else
|
83
|
+
module_name = to_type_name(const_name(mix))
|
84
|
+
if module_name.namespace == type_name.namespace
|
85
|
+
module_name = TypeName.new(name: module_name.name, namespace: Namespace.empty)
|
86
|
+
end
|
87
|
+
|
88
|
+
yield module_name, mix
|
89
|
+
end
|
69
90
|
end
|
70
91
|
end
|
71
92
|
end
|
@@ -298,11 +319,11 @@ module RBS
|
|
298
319
|
location: nil
|
299
320
|
)
|
300
321
|
else
|
301
|
-
Types::ClassInstance.new(name: to_type_name(value.class
|
322
|
+
Types::ClassInstance.new(name: to_type_name(const_name(value.class)), args: [], location: nil)
|
302
323
|
end
|
303
324
|
|
304
325
|
@decls << AST::Declarations::Constant.new(
|
305
|
-
name: "#{mod
|
326
|
+
name: "#{const_name(mod)}::#{name}",
|
306
327
|
type: type,
|
307
328
|
location: nil,
|
308
329
|
comment: nil
|
@@ -311,14 +332,14 @@ module RBS
|
|
311
332
|
end
|
312
333
|
|
313
334
|
def generate_class(mod)
|
314
|
-
type_name = to_type_name(mod
|
335
|
+
type_name = to_type_name(const_name(mod))
|
315
336
|
super_class = if mod.superclass == ::Object
|
316
337
|
nil
|
317
|
-
elsif mod.superclass.
|
338
|
+
elsif const_name(mod.superclass).nil?
|
318
339
|
RBS.logger.warn("Skipping anonymous superclass #{mod.superclass} of #{mod}")
|
319
340
|
nil
|
320
341
|
else
|
321
|
-
AST::Declarations::Class::Super.new(name: to_type_name(mod.superclass
|
342
|
+
AST::Declarations::Class::Super.new(name: to_type_name(const_name(mod.superclass)), args: [], location: nil)
|
322
343
|
end
|
323
344
|
|
324
345
|
decl = AST::Declarations::Class.new(
|
@@ -331,17 +352,7 @@ module RBS
|
|
331
352
|
comment: nil
|
332
353
|
)
|
333
354
|
|
334
|
-
|
335
|
-
unless included_module.name
|
336
|
-
RBS.logger.warn("Skipping anonymous module #{included_module} included in #{mod}")
|
337
|
-
next
|
338
|
-
end
|
339
|
-
|
340
|
-
module_name = to_type_name(included_module.name)
|
341
|
-
if module_name.namespace == type_name.namespace
|
342
|
-
module_name = TypeName.new(name: module_name.name, namespace: Namespace.empty)
|
343
|
-
end
|
344
|
-
|
355
|
+
each_included_module(type_name, mod) do |module_name, _|
|
345
356
|
decl.members << AST::Members::Include.new(
|
346
357
|
name: module_name,
|
347
358
|
args: [],
|
@@ -351,6 +362,16 @@ module RBS
|
|
351
362
|
)
|
352
363
|
end
|
353
364
|
|
365
|
+
each_included_module(type_name, mod.singleton_class) do |module_name, _|
|
366
|
+
decl.members << AST::Members::Extend.new(
|
367
|
+
name: module_name,
|
368
|
+
args: [],
|
369
|
+
location: nil,
|
370
|
+
comment: nil,
|
371
|
+
annotations: []
|
372
|
+
)
|
373
|
+
end
|
374
|
+
|
354
375
|
generate_methods(mod, type_name, decl.members)
|
355
376
|
|
356
377
|
@decls << decl
|
@@ -378,18 +399,7 @@ module RBS
|
|
378
399
|
comment: nil
|
379
400
|
)
|
380
401
|
|
381
|
-
|
382
|
-
included_module_name = const_name(included_module)
|
383
|
-
unless included_module_name
|
384
|
-
RBS.logger.warn("Skipping anonymous module #{included_module} included in #{mod}")
|
385
|
-
next
|
386
|
-
end
|
387
|
-
|
388
|
-
module_name = to_type_name(included_module_name)
|
389
|
-
if module_name.namespace == type_name.namespace
|
390
|
-
module_name = TypeName.new(name: module_name.name, namespace: Namespace.empty)
|
391
|
-
end
|
392
|
-
|
402
|
+
each_included_module(type_name, mod) do |module_name, _|
|
393
403
|
decl.members << AST::Members::Include.new(
|
394
404
|
name: module_name,
|
395
405
|
args: [],
|
@@ -399,6 +409,16 @@ module RBS
|
|
399
409
|
)
|
400
410
|
end
|
401
411
|
|
412
|
+
each_included_module(type_name, mod.singleton_class) do |module_name, _|
|
413
|
+
decl.members << AST::Members::Extend.new(
|
414
|
+
name: module_name,
|
415
|
+
args: [],
|
416
|
+
location: nil,
|
417
|
+
comment: nil,
|
418
|
+
annotations: []
|
419
|
+
)
|
420
|
+
end
|
421
|
+
|
402
422
|
generate_methods(mod, type_name, decl.members)
|
403
423
|
|
404
424
|
@decls << decl
|
data/lib/rbs/substitution.rb
CHANGED
data/lib/rbs/test.rb
CHANGED
data/lib/rbs/test/hook.rb
CHANGED
@@ -67,12 +67,19 @@ module RBS
|
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
|
-
def self.hook_method_source(prefix, method_name, key, random:)
|
70
|
+
def self.hook_method_source(prefix, method_name, key, random:, params:)
|
71
71
|
with_name, without_name = alias_names(method_name, random)
|
72
72
|
full_method_name = "#{prefix}#{method_name}"
|
73
73
|
|
74
|
+
param_source = params.take_while {|param| param[0] == :req }.map(&:last) + ["*rest_args_#{random}"]
|
75
|
+
|
76
|
+
RBS.logger.debug {
|
77
|
+
"Generating method definition: def #{with_name}(#{param_source.join(", ")}, &block) ..."
|
78
|
+
}
|
79
|
+
|
74
80
|
[__LINE__ + 1, <<RUBY]
|
75
|
-
def #{with_name}(
|
81
|
+
def #{with_name}(#{param_source.join(", ")}, &block)
|
82
|
+
args = [#{param_source.join(", ")}]
|
76
83
|
::RBS.logger.debug { "#{full_method_name} with arguments: [" + args.map(&:inspect).join(", ") + "]" }
|
77
84
|
|
78
85
|
begin
|
@@ -81,13 +88,18 @@ def #{with_name}(*args, &block)
|
|
81
88
|
|
82
89
|
if block_given?
|
83
90
|
receiver = self
|
91
|
+
block_receives_block = block.parameters.last&.yield_self {|type, _| type == :block }
|
84
92
|
|
85
|
-
wrapped_block = proc do |*block_args|
|
93
|
+
wrapped_block = proc do |*block_args, &block2|
|
86
94
|
return_from_block = false
|
87
95
|
|
88
96
|
begin
|
89
97
|
block_result = if receiver.equal?(self)
|
90
|
-
|
98
|
+
if block_receives_block
|
99
|
+
block.call(*block_args, &block2)
|
100
|
+
else
|
101
|
+
yield(*block_args)
|
102
|
+
end
|
91
103
|
else
|
92
104
|
instance_exec(*block_args, &block)
|
93
105
|
end
|
@@ -166,7 +178,8 @@ RUBY
|
|
166
178
|
|
167
179
|
def self.hook_instance_method(klass, method, key:)
|
168
180
|
random = SecureRandom.hex(4)
|
169
|
-
|
181
|
+
params = klass.instance_method(method).parameters
|
182
|
+
line, source = hook_method_source("#{klass}#", method, key, random: random, params: params)
|
170
183
|
|
171
184
|
klass.module_eval(source, __FILE__, line)
|
172
185
|
setup_alias_method_chain klass, method, random: random
|
@@ -174,7 +187,8 @@ RUBY
|
|
174
187
|
|
175
188
|
def self.hook_singleton_method(klass, method, key:)
|
176
189
|
random = SecureRandom.hex(4)
|
177
|
-
|
190
|
+
params = klass.method(method).parameters
|
191
|
+
line, source = hook_method_source("#{klass}.",method, key, random: random, params: params)
|
178
192
|
|
179
193
|
klass.singleton_class.module_eval(source, __FILE__, line)
|
180
194
|
setup_alias_method_chain klass.singleton_class, method, random: random
|
data/lib/rbs/validator.rb
CHANGED
@@ -18,8 +18,9 @@ module RBS
|
|
18
18
|
def validate_type(type, context:)
|
19
19
|
case type
|
20
20
|
when Types::ClassInstance, Types::Interface
|
21
|
+
# @type var type: Types::ClassInstance | Types::Interface
|
21
22
|
if type.name.namespace.relative?
|
22
|
-
type = absolute_type(type, context: context) do |
|
23
|
+
type = _ = absolute_type(type, context: context) do |_|
|
23
24
|
NoTypeFoundError.check!(type.name.absolute!, env: env, location: type.location)
|
24
25
|
end
|
25
26
|
end
|
@@ -43,7 +44,8 @@ module RBS
|
|
43
44
|
)
|
44
45
|
|
45
46
|
when Types::Alias, Types::ClassSingleton
|
46
|
-
type
|
47
|
+
# @type var type: Types::Alias | Types::ClassSingleton
|
48
|
+
type = _ = absolute_type(type, context: context) { type.name.absolute! }
|
47
49
|
NoTypeFoundError.check!(type.name, env: env, location: type.location)
|
48
50
|
end
|
49
51
|
|
@@ -86,7 +86,11 @@ module RBS
|
|
86
86
|
end
|
87
87
|
|
88
88
|
def in_inherit(name:, args:, variables:)
|
89
|
-
type =
|
89
|
+
type = if name.class?
|
90
|
+
Types::ClassInstance.new(name: name, args: args, location: nil)
|
91
|
+
else
|
92
|
+
Types::Interface.new(name: name, args: args, location: nil)
|
93
|
+
end
|
90
94
|
|
91
95
|
Result.new(variables: variables).tap do |result|
|
92
96
|
type(type, result: result, context: :covariant)
|
data/lib/rbs/version.rb
CHANGED
data/sig/definition.rbs
CHANGED
@@ -65,10 +65,15 @@ module RBS
|
|
65
65
|
type t = Instance | Singleton
|
66
66
|
|
67
67
|
class Instance
|
68
|
+
type source = :super | nil
|
69
|
+
| AST::Members::Include | AST::Members::Extend | AST::Members::Prepend
|
70
|
+
| AST::Declarations::Module::Self
|
71
|
+
|
68
72
|
attr_reader name: TypeName
|
69
73
|
attr_reader args: Array[Types::t]
|
74
|
+
attr_reader source: source
|
70
75
|
|
71
|
-
def initialize: (name: TypeName, args: Array[Types::t]) -> void
|
76
|
+
def initialize: (name: TypeName, args: Array[Types::t], source: source) -> void
|
72
77
|
end
|
73
78
|
|
74
79
|
class Singleton
|
data/sig/errors.rbs
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
module RBS
|
2
|
+
interface _Kinded
|
3
|
+
def kind: () -> (:instance | :singleton)
|
4
|
+
end
|
5
|
+
|
6
|
+
module MethodNameHelper : _Kinded
|
7
|
+
def method_name_string: () -> String
|
8
|
+
end
|
9
|
+
|
10
|
+
class InvalidTypeApplicationError < StandardError
|
11
|
+
attr_reader type_name: TypeName
|
12
|
+
attr_reader args: Array[Types::t]
|
13
|
+
attr_reader params: Array[Symbol]
|
14
|
+
attr_reader location: Location?
|
15
|
+
|
16
|
+
def initialize: (type_name: TypeName, args: Array[Types::t], params: Array[Symbol], location: Location?) -> void
|
17
|
+
|
18
|
+
def self.check!: (type_name: TypeName, args: Array[Types::t], params: Array[Symbol], location: Location?) -> void
|
19
|
+
end
|
20
|
+
end
|
data/sig/type_name_resolver.rbs
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
module RBS
|
2
2
|
class TypeNameResolver
|
3
|
+
type context = Array[Namespace]
|
4
|
+
|
3
5
|
class Query
|
4
6
|
attr_reader type_name: TypeName
|
5
7
|
attr_reader context: Array[Namespace]
|
6
8
|
|
7
|
-
def initialize: (type_name: TypeName, context:
|
9
|
+
def initialize: (type_name: TypeName, context: context) -> void
|
8
10
|
end
|
9
11
|
|
10
12
|
attr_reader all_names: Set[TypeName]
|
@@ -15,7 +17,7 @@ module RBS
|
|
15
17
|
|
16
18
|
def add_names: (Array[TypeName]) -> self
|
17
19
|
|
18
|
-
def resolve: (TypeName, context:
|
20
|
+
def resolve: (TypeName, context: context) -> TypeName?
|
19
21
|
|
20
22
|
def has_name?: (TypeName) -> TypeName?
|
21
23
|
|
data/sig/validator.rbs
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
module RBS
|
2
|
+
class Validator
|
3
|
+
attr_reader env: Environment
|
4
|
+
attr_reader resolver: TypeNameResolver
|
5
|
+
|
6
|
+
def initialize: (env: Environment, resolver: TypeNameResolver) -> void
|
7
|
+
|
8
|
+
def absolute_type: (Types::t, context: TypeNameResolver::context) { (Types::t) -> TypeName } -> Types::t
|
9
|
+
|
10
|
+
def validate_type: (Types::t, context: TypeNameResolver::context) -> void
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,327 @@
|
|
1
|
+
class Time
|
2
|
+
interface _TimeLike
|
3
|
+
def year: () -> Integer
|
4
|
+
def mon: () -> Integer
|
5
|
+
def day: () -> Integer
|
6
|
+
end
|
7
|
+
|
8
|
+
#
|
9
|
+
# Return the number of seconds the specified time zone differs
|
10
|
+
# from UTC.
|
11
|
+
#
|
12
|
+
# Numeric time zones that include minutes, such as
|
13
|
+
# <code>-10:00</code> or <code>+1330</code> will work, as will
|
14
|
+
# simpler hour-only time zones like <code>-10</code> or
|
15
|
+
# <code>+13</code>.
|
16
|
+
#
|
17
|
+
# Textual time zones listed in ZoneOffset are also supported.
|
18
|
+
#
|
19
|
+
# If the time zone does not match any of the above, +zone_offset+
|
20
|
+
# will check if the local time zone (both with and without
|
21
|
+
# potential Daylight Saving \Time changes being in effect) matches
|
22
|
+
# +zone+. Specifying a value for +year+ will change the year used
|
23
|
+
# to find the local time zone.
|
24
|
+
#
|
25
|
+
# If +zone_offset+ is unable to determine the offset, nil will be
|
26
|
+
# returned.
|
27
|
+
#
|
28
|
+
# require 'time'
|
29
|
+
#
|
30
|
+
# Time.zone_offset("EST") #=> -18000
|
31
|
+
#
|
32
|
+
# You must require 'time' to use this method.
|
33
|
+
#
|
34
|
+
def self.zone_offset: (String zone, ?Integer year) -> Integer
|
35
|
+
|
36
|
+
#
|
37
|
+
# Takes a string representation of a Time and attempts to parse it
|
38
|
+
# using a heuristic.
|
39
|
+
#
|
40
|
+
# require 'time'
|
41
|
+
#
|
42
|
+
# Time.parse("2010-10-31") #=> 2010-10-31 00:00:00 -0500
|
43
|
+
#
|
44
|
+
# Any missing pieces of the date are inferred based on the current date.
|
45
|
+
#
|
46
|
+
# require 'time'
|
47
|
+
#
|
48
|
+
# # assuming the current date is "2011-10-31"
|
49
|
+
# Time.parse("12:00") #=> 2011-10-31 12:00:00 -0500
|
50
|
+
#
|
51
|
+
# We can change the date used to infer our missing elements by passing a second
|
52
|
+
# object that responds to #mon, #day and #year, such as Date, Time or DateTime.
|
53
|
+
# We can also use our own object.
|
54
|
+
#
|
55
|
+
# require 'time'
|
56
|
+
#
|
57
|
+
# class MyDate
|
58
|
+
# attr_reader :mon, :day, :year
|
59
|
+
#
|
60
|
+
# def initialize(mon, day, year)
|
61
|
+
# @mon, @day, @year = mon, day, year
|
62
|
+
# end
|
63
|
+
# end
|
64
|
+
#
|
65
|
+
# d = Date.parse("2010-10-28")
|
66
|
+
# t = Time.parse("2010-10-29")
|
67
|
+
# dt = DateTime.parse("2010-10-30")
|
68
|
+
# md = MyDate.new(10,31,2010)
|
69
|
+
#
|
70
|
+
# Time.parse("12:00", d) #=> 2010-10-28 12:00:00 -0500
|
71
|
+
# Time.parse("12:00", t) #=> 2010-10-29 12:00:00 -0500
|
72
|
+
# Time.parse("12:00", dt) #=> 2010-10-30 12:00:00 -0500
|
73
|
+
# Time.parse("12:00", md) #=> 2010-10-31 12:00:00 -0500
|
74
|
+
#
|
75
|
+
# If a block is given, the year described in +date+ is converted
|
76
|
+
# by the block. This is specifically designed for handling two
|
77
|
+
# digit years. For example, if you wanted to treat all two digit
|
78
|
+
# years prior to 70 as the year 2000+ you could write this:
|
79
|
+
#
|
80
|
+
# require 'time'
|
81
|
+
#
|
82
|
+
# Time.parse("01-10-31") {|year| year + (year < 70 ? 2000 : 1900)}
|
83
|
+
# #=> 2001-10-31 00:00:00 -0500
|
84
|
+
# Time.parse("70-10-31") {|year| year + (year < 70 ? 2000 : 1900)}
|
85
|
+
# #=> 1970-10-31 00:00:00 -0500
|
86
|
+
#
|
87
|
+
# If the upper components of the given time are broken or missing, they are
|
88
|
+
# supplied with those of +now+. For the lower components, the minimum
|
89
|
+
# values (1 or 0) are assumed if broken or missing. For example:
|
90
|
+
#
|
91
|
+
# require 'time'
|
92
|
+
#
|
93
|
+
# # Suppose it is "Thu Nov 29 14:33:20 2001" now and
|
94
|
+
# # your time zone is EST which is GMT-5.
|
95
|
+
# now = Time.parse("Thu Nov 29 14:33:20 2001")
|
96
|
+
# Time.parse("16:30", now) #=> 2001-11-29 16:30:00 -0500
|
97
|
+
# Time.parse("7/23", now) #=> 2001-07-23 00:00:00 -0500
|
98
|
+
# Time.parse("Aug 31", now) #=> 2001-08-31 00:00:00 -0500
|
99
|
+
# Time.parse("Aug 2000", now) #=> 2000-08-01 00:00:00 -0500
|
100
|
+
#
|
101
|
+
# Since there are numerous conflicts among locally defined time zone
|
102
|
+
# abbreviations all over the world, this method is not intended to
|
103
|
+
# understand all of them. For example, the abbreviation "CST" is
|
104
|
+
# used variously as:
|
105
|
+
#
|
106
|
+
# -06:00 in America/Chicago,
|
107
|
+
# -05:00 in America/Havana,
|
108
|
+
# +08:00 in Asia/Harbin,
|
109
|
+
# +09:30 in Australia/Darwin,
|
110
|
+
# +10:30 in Australia/Adelaide,
|
111
|
+
# etc.
|
112
|
+
#
|
113
|
+
# Based on this fact, this method only understands the time zone
|
114
|
+
# abbreviations described in RFC 822 and the system time zone, in the
|
115
|
+
# order named. (i.e. a definition in RFC 822 overrides the system
|
116
|
+
# time zone definition.) The system time zone is taken from
|
117
|
+
# <tt>Time.local(year, 1, 1).zone</tt> and
|
118
|
+
# <tt>Time.local(year, 7, 1).zone</tt>.
|
119
|
+
# If the extracted time zone abbreviation does not match any of them,
|
120
|
+
# it is ignored and the given time is regarded as a local time.
|
121
|
+
#
|
122
|
+
# ArgumentError is raised if Date._parse cannot extract information from
|
123
|
+
# +date+ or if the Time class cannot represent specified date.
|
124
|
+
#
|
125
|
+
# This method can be used as a fail-safe for other parsing methods as:
|
126
|
+
#
|
127
|
+
# Time.rfc2822(date) rescue Time.parse(date)
|
128
|
+
# Time.httpdate(date) rescue Time.parse(date)
|
129
|
+
# Time.xmlschema(date) rescue Time.parse(date)
|
130
|
+
#
|
131
|
+
# A failure of Time.parse should be checked, though.
|
132
|
+
#
|
133
|
+
# You must require 'time' to use this method.
|
134
|
+
#
|
135
|
+
def self.parse: (String date, ?_TimeLike now) ?{ (Integer) -> Integer } -> Time
|
136
|
+
|
137
|
+
#
|
138
|
+
# Works similar to +parse+ except that instead of using a
|
139
|
+
# heuristic to detect the format of the input string, you provide
|
140
|
+
# a second argument that describes the format of the string.
|
141
|
+
#
|
142
|
+
# If a block is given, the year described in +date+ is converted by the
|
143
|
+
# block. For example:
|
144
|
+
#
|
145
|
+
# Time.strptime(...) {|y| y < 100 ? (y >= 69 ? y + 1900 : y + 2000) : y}
|
146
|
+
#
|
147
|
+
# Below is a list of the formatting options:
|
148
|
+
#
|
149
|
+
# %a :: The abbreviated weekday name ("Sun")
|
150
|
+
# %A :: The full weekday name ("Sunday")
|
151
|
+
# %b :: The abbreviated month name ("Jan")
|
152
|
+
# %B :: The full month name ("January")
|
153
|
+
# %c :: The preferred local date and time representation
|
154
|
+
# %C :: Century (20 in 2009)
|
155
|
+
# %d :: Day of the month (01..31)
|
156
|
+
# %D :: Date (%m/%d/%y)
|
157
|
+
# %e :: Day of the month, blank-padded ( 1..31)
|
158
|
+
# %F :: Equivalent to %Y-%m-%d (the ISO 8601 date format)
|
159
|
+
# %g :: The last two digits of the commercial year
|
160
|
+
# %G :: The week-based year according to ISO-8601 (week 1 starts on Monday
|
161
|
+
# and includes January 4)
|
162
|
+
# %h :: Equivalent to %b
|
163
|
+
# %H :: Hour of the day, 24-hour clock (00..23)
|
164
|
+
# %I :: Hour of the day, 12-hour clock (01..12)
|
165
|
+
# %j :: Day of the year (001..366)
|
166
|
+
# %k :: hour, 24-hour clock, blank-padded ( 0..23)
|
167
|
+
# %l :: hour, 12-hour clock, blank-padded ( 0..12)
|
168
|
+
# %L :: Millisecond of the second (000..999)
|
169
|
+
# %m :: Month of the year (01..12)
|
170
|
+
# %M :: Minute of the hour (00..59)
|
171
|
+
# %n :: Newline (\n)
|
172
|
+
# %N :: Fractional seconds digits
|
173
|
+
# %p :: Meridian indicator ("AM" or "PM")
|
174
|
+
# %P :: Meridian indicator ("am" or "pm")
|
175
|
+
# %r :: time, 12-hour (same as %I:%M:%S %p)
|
176
|
+
# %R :: time, 24-hour (%H:%M)
|
177
|
+
# %s :: Number of seconds since 1970-01-01 00:00:00 UTC.
|
178
|
+
# %S :: Second of the minute (00..60)
|
179
|
+
# %t :: Tab character (\t)
|
180
|
+
# %T :: time, 24-hour (%H:%M:%S)
|
181
|
+
# %u :: Day of the week as a decimal, Monday being 1. (1..7)
|
182
|
+
# %U :: Week number of the current year, starting with the first Sunday as
|
183
|
+
# the first day of the first week (00..53)
|
184
|
+
# %v :: VMS date (%e-%b-%Y)
|
185
|
+
# %V :: Week number of year according to ISO 8601 (01..53)
|
186
|
+
# %W :: Week number of the current year, starting with the first Monday
|
187
|
+
# as the first day of the first week (00..53)
|
188
|
+
# %w :: Day of the week (Sunday is 0, 0..6)
|
189
|
+
# %x :: Preferred representation for the date alone, no time
|
190
|
+
# %X :: Preferred representation for the time alone, no date
|
191
|
+
# %y :: Year without a century (00..99)
|
192
|
+
# %Y :: Year which may include century, if provided
|
193
|
+
# %z :: Time zone as hour offset from UTC (e.g. +0900)
|
194
|
+
# %Z :: Time zone name
|
195
|
+
# %% :: Literal "%" character
|
196
|
+
# %+ :: date(1) (%a %b %e %H:%M:%S %Z %Y)
|
197
|
+
#
|
198
|
+
# require 'time'
|
199
|
+
#
|
200
|
+
# Time.strptime("2000-10-31", "%Y-%m-%d") #=> 2000-10-31 00:00:00 -0500
|
201
|
+
#
|
202
|
+
# You must require 'time' to use this method.
|
203
|
+
#
|
204
|
+
def self.strptime: (String date, String format, ?_TimeLike now) ?{ (Integer) -> Integer } -> Time
|
205
|
+
|
206
|
+
#
|
207
|
+
# Parses +date+ as date-time defined by RFC 2822 and converts it to a Time
|
208
|
+
# object. The format is identical to the date format defined by RFC 822 and
|
209
|
+
# updated by RFC 1123.
|
210
|
+
#
|
211
|
+
# ArgumentError is raised if +date+ is not compliant with RFC 2822
|
212
|
+
# or if the Time class cannot represent specified date.
|
213
|
+
#
|
214
|
+
# See #rfc2822 for more information on this format.
|
215
|
+
#
|
216
|
+
# require 'time'
|
217
|
+
#
|
218
|
+
# Time.rfc2822("Wed, 05 Oct 2011 22:26:12 -0400")
|
219
|
+
# #=> 2010-10-05 22:26:12 -0400
|
220
|
+
#
|
221
|
+
# You must require 'time' to use this method.
|
222
|
+
#
|
223
|
+
def self.rfc2822: (String date) -> Time
|
224
|
+
|
225
|
+
alias self.rfc822 self.rfc2822
|
226
|
+
|
227
|
+
#
|
228
|
+
# Parses +date+ as an HTTP-date defined by RFC 2616 and converts it to a
|
229
|
+
# Time object.
|
230
|
+
#
|
231
|
+
# ArgumentError is raised if +date+ is not compliant with RFC 2616 or if
|
232
|
+
# the Time class cannot represent specified date.
|
233
|
+
#
|
234
|
+
# See #httpdate for more information on this format.
|
235
|
+
#
|
236
|
+
# require 'time'
|
237
|
+
#
|
238
|
+
# Time.httpdate("Thu, 06 Oct 2011 02:26:12 GMT")
|
239
|
+
# #=> 2011-10-06 02:26:12 UTC
|
240
|
+
#
|
241
|
+
# You must require 'time' to use this method.
|
242
|
+
#
|
243
|
+
def self.httpdate: (String date) -> Time
|
244
|
+
|
245
|
+
#
|
246
|
+
# Parses +date+ as a dateTime defined by the XML Schema and converts it to
|
247
|
+
# a Time object. The format is a restricted version of the format defined
|
248
|
+
# by ISO 8601.
|
249
|
+
#
|
250
|
+
# ArgumentError is raised if +date+ is not compliant with the format or if
|
251
|
+
# the Time class cannot represent specified date.
|
252
|
+
#
|
253
|
+
# See #xmlschema for more information on this format.
|
254
|
+
#
|
255
|
+
# require 'time'
|
256
|
+
#
|
257
|
+
# Time.xmlschema("2011-10-05T22:26:12-04:00")
|
258
|
+
# #=> 2011-10-05 22:26:12-04:00
|
259
|
+
#
|
260
|
+
# You must require 'time' to use this method.
|
261
|
+
#
|
262
|
+
def self.xmlschema: (String date) -> Time
|
263
|
+
|
264
|
+
alias self.iso8601 self.xmlschema
|
265
|
+
|
266
|
+
#
|
267
|
+
# Returns a string which represents the time as date-time defined by RFC 2822:
|
268
|
+
#
|
269
|
+
# day-of-week, DD month-name CCYY hh:mm:ss zone
|
270
|
+
#
|
271
|
+
# where zone is [+-]hhmm.
|
272
|
+
#
|
273
|
+
# If +self+ is a UTC time, -0000 is used as zone.
|
274
|
+
#
|
275
|
+
# require 'time'
|
276
|
+
#
|
277
|
+
# t = Time.now
|
278
|
+
# t.rfc2822 # => "Wed, 05 Oct 2011 22:26:12 -0400"
|
279
|
+
#
|
280
|
+
# You must require 'time' to use this method.
|
281
|
+
#
|
282
|
+
def rfc2822: () -> String
|
283
|
+
|
284
|
+
alias rfc822 rfc2822
|
285
|
+
|
286
|
+
#
|
287
|
+
# Returns a string which represents the time as RFC 1123 date of HTTP-date
|
288
|
+
# defined by RFC 2616:
|
289
|
+
#
|
290
|
+
# day-of-week, DD month-name CCYY hh:mm:ss GMT
|
291
|
+
#
|
292
|
+
# Note that the result is always UTC (GMT).
|
293
|
+
#
|
294
|
+
# require 'time'
|
295
|
+
#
|
296
|
+
# t = Time.now
|
297
|
+
# t.httpdate # => "Thu, 06 Oct 2011 02:26:12 GMT"
|
298
|
+
#
|
299
|
+
# You must require 'time' to use this method.
|
300
|
+
#
|
301
|
+
def httpdate: () -> String
|
302
|
+
|
303
|
+
#
|
304
|
+
# Returns a string which represents the time as a dateTime defined by XML
|
305
|
+
# Schema:
|
306
|
+
#
|
307
|
+
# CCYY-MM-DDThh:mm:ssTZD
|
308
|
+
# CCYY-MM-DDThh:mm:ss.sssTZD
|
309
|
+
#
|
310
|
+
# where TZD is Z or [+-]hh:mm.
|
311
|
+
#
|
312
|
+
# If self is a UTC time, Z is used as TZD. [+-]hh:mm is used otherwise.
|
313
|
+
#
|
314
|
+
# +fractional_digits+ specifies a number of digits to use for fractional
|
315
|
+
# seconds. Its default value is 0.
|
316
|
+
#
|
317
|
+
# require 'time'
|
318
|
+
#
|
319
|
+
# t = Time.now
|
320
|
+
# t.iso8601 # => "2011-10-05T22:26:12-04:00"
|
321
|
+
#
|
322
|
+
# You must require 'time' to use this method.
|
323
|
+
#
|
324
|
+
def xmlschema: (?Integer fraction_digits) -> String
|
325
|
+
|
326
|
+
alias iso8601 xmlschema
|
327
|
+
end
|