rbs 0.18.0 → 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 +31 -0
- data/Rakefile +4 -0
- data/core/builtin.rbs +4 -0
- data/core/file.rbs +0 -4
- data/core/hash.rbs +1 -3
- data/core/io.rbs +159 -6
- data/core/kernel.rbs +1 -1
- data/core/time.rbs +0 -12
- 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 +10 -4
- data/lib/rbs/cli.rb +10 -10
- data/lib/rbs/definition.rb +70 -3
- data/lib/rbs/definition_builder.rb +544 -989
- 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 +5 -1
- data/lib/rbs/environment_loader.rb +1 -1
- data/lib/rbs/environment_walker.rb +16 -10
- data/lib/rbs/errors.rb +71 -66
- data/lib/rbs/method_type.rb +1 -31
- data/lib/rbs/parser.rb +1000 -894
- data/lib/rbs/parser.y +108 -57
- data/lib/rbs/prototype/rb.rb +14 -3
- data/lib/rbs/prototype/rbi.rb +6 -6
- data/lib/rbs/prototype/runtime.rb +53 -33
- data/lib/rbs/substitution.rb +4 -0
- data/lib/rbs/test.rb +3 -1
- data/lib/rbs/test/hook.rb +24 -7
- data/lib/rbs/types.rb +63 -6
- data/lib/rbs/validator.rb +4 -2
- data/lib/rbs/variance_calculator.rb +5 -1
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs/writer.rb +9 -1
- data/schema/members.json +5 -1
- data/sig/definition.rbs +6 -1
- data/sig/definition_builder.rbs +3 -0
- data/sig/errors.rbs +20 -0
- data/sig/members.rbs +4 -1
- data/sig/method_types.rbs +3 -16
- data/sig/type_name_resolver.rbs +4 -2
- data/sig/types.rbs +17 -1
- data/sig/validator.rbs +12 -0
- data/stdlib/dbm/0/dbm.rbs +0 -2
- data/stdlib/logger/0/log_device.rbs +1 -2
- data/stdlib/monitor/0/monitor.rbs +119 -0
- data/stdlib/time/0/time.rbs +327 -0
- data/stdlib/tsort/0/tsort.rbs +8 -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 +13 -14
- metadata +14 -5
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,12 +88,18 @@ def #{with_name}(*args, &block)
|
|
81
88
|
|
82
89
|
if block_given?
|
83
90
|
receiver = self
|
84
|
-
|
91
|
+
block_receives_block = block.parameters.last&.yield_self {|type, _| type == :block }
|
92
|
+
|
93
|
+
wrapped_block = proc do |*block_args, &block2|
|
85
94
|
return_from_block = false
|
86
95
|
|
87
96
|
begin
|
88
97
|
block_result = if receiver.equal?(self)
|
89
|
-
|
98
|
+
if block_receives_block
|
99
|
+
block.call(*block_args, &block2)
|
100
|
+
else
|
101
|
+
yield(*block_args)
|
102
|
+
end
|
90
103
|
else
|
91
104
|
instance_exec(*block_args, &block)
|
92
105
|
end
|
@@ -117,7 +130,9 @@ def #{with_name}(*args, &block)
|
|
117
130
|
end
|
118
131
|
|
119
132
|
block_result
|
120
|
-
end
|
133
|
+
end.ruby2_keywords
|
134
|
+
|
135
|
+
result = __send__(:"#{without_name}", *args, &wrapped_block)
|
121
136
|
else
|
122
137
|
result = __send__(:"#{without_name}", *args)
|
123
138
|
end
|
@@ -163,7 +178,8 @@ RUBY
|
|
163
178
|
|
164
179
|
def self.hook_instance_method(klass, method, key:)
|
165
180
|
random = SecureRandom.hex(4)
|
166
|
-
|
181
|
+
params = klass.instance_method(method).parameters
|
182
|
+
line, source = hook_method_source("#{klass}#", method, key, random: random, params: params)
|
167
183
|
|
168
184
|
klass.module_eval(source, __FILE__, line)
|
169
185
|
setup_alias_method_chain klass, method, random: random
|
@@ -171,7 +187,8 @@ RUBY
|
|
171
187
|
|
172
188
|
def self.hook_singleton_method(klass, method, key:)
|
173
189
|
random = SecureRandom.hex(4)
|
174
|
-
|
190
|
+
params = klass.method(method).parameters
|
191
|
+
line, source = hook_method_source("#{klass}.",method, key, random: random, params: params)
|
175
192
|
|
176
193
|
klass.singleton_class.module_eval(source, __FILE__, line)
|
177
194
|
setup_alias_method_chain klass.singleton_class, method, random: random
|
data/lib/rbs/types.rb
CHANGED
@@ -947,44 +947,100 @@ module RBS
|
|
947
947
|
end
|
948
948
|
end
|
949
949
|
|
950
|
+
class Block
|
951
|
+
attr_reader :type
|
952
|
+
attr_reader :required
|
953
|
+
|
954
|
+
def initialize(type:, required:)
|
955
|
+
@type = type
|
956
|
+
@required = required
|
957
|
+
end
|
958
|
+
|
959
|
+
def ==(other)
|
960
|
+
other.is_a?(Block) &&
|
961
|
+
other.type == type &&
|
962
|
+
other.required == required
|
963
|
+
end
|
964
|
+
|
965
|
+
def to_json(*a)
|
966
|
+
{
|
967
|
+
type: type,
|
968
|
+
required: required
|
969
|
+
}.to_json(*a)
|
970
|
+
end
|
971
|
+
|
972
|
+
def sub(s)
|
973
|
+
self.class.new(
|
974
|
+
type: type.sub(s),
|
975
|
+
required: required
|
976
|
+
)
|
977
|
+
end
|
978
|
+
|
979
|
+
def map_type(&block)
|
980
|
+
Block.new(
|
981
|
+
required: required,
|
982
|
+
type: type.map_type(&block)
|
983
|
+
)
|
984
|
+
end
|
985
|
+
end
|
986
|
+
|
950
987
|
class Proc
|
951
988
|
attr_reader :type
|
989
|
+
attr_reader :block
|
952
990
|
attr_reader :location
|
953
991
|
|
954
|
-
def initialize(location:, type:)
|
992
|
+
def initialize(location:, type:, block:)
|
955
993
|
@type = type
|
994
|
+
@block = block
|
956
995
|
@location = location
|
957
996
|
end
|
958
997
|
|
959
998
|
def ==(other)
|
960
|
-
other.is_a?(Proc) && other.type == type
|
999
|
+
other.is_a?(Proc) && other.type == type && other.block == block
|
961
1000
|
end
|
962
1001
|
|
963
1002
|
alias eql? ==
|
964
1003
|
|
965
1004
|
def hash
|
966
|
-
self.class.hash ^ type.hash
|
1005
|
+
self.class.hash ^ type.hash ^ block.hash
|
967
1006
|
end
|
968
1007
|
|
969
1008
|
def free_variables(set = Set[])
|
970
1009
|
type.free_variables(set)
|
1010
|
+
block&.type&.free_variables(set)
|
1011
|
+
set
|
971
1012
|
end
|
972
1013
|
|
973
1014
|
def to_json(*a)
|
974
|
-
{
|
1015
|
+
{
|
1016
|
+
class: :proc,
|
1017
|
+
type: type,
|
1018
|
+
block: block,
|
1019
|
+
location: location
|
1020
|
+
}.to_json(*a)
|
975
1021
|
end
|
976
1022
|
|
977
1023
|
def sub(s)
|
978
|
-
self.class.new(type: type.sub(s), location: location)
|
1024
|
+
self.class.new(type: type.sub(s), block: block&.sub(s), location: location)
|
979
1025
|
end
|
980
1026
|
|
981
1027
|
def to_s(level = 0)
|
982
|
-
|
1028
|
+
case
|
1029
|
+
when b = block
|
1030
|
+
if b.required
|
1031
|
+
"^(#{type.param_to_s}) { (#{b.type.param_to_s}) -> #{b.type.return_to_s} } -> #{type.return_to_s}"
|
1032
|
+
else
|
1033
|
+
"^(#{type.param_to_s}) ?{ (#{b.type.param_to_s}) -> #{b.type.return_to_s} } -> #{type.return_to_s}"
|
1034
|
+
end
|
1035
|
+
else
|
1036
|
+
"^(#{type.param_to_s}) -> #{type.return_to_s}"
|
1037
|
+
end
|
983
1038
|
end
|
984
1039
|
|
985
1040
|
def each_type(&block)
|
986
1041
|
if block
|
987
1042
|
type.each_type(&block)
|
1043
|
+
self.block&.type&.each_type(&block)
|
988
1044
|
else
|
989
1045
|
enum_for :each_type
|
990
1046
|
end
|
@@ -993,6 +1049,7 @@ module RBS
|
|
993
1049
|
def map_type_name(&block)
|
994
1050
|
Proc.new(
|
995
1051
|
type: type.map_type_name(&block),
|
1052
|
+
block: self.block&.map_type {|type| type.map_type_name(&block) },
|
996
1053
|
location: location
|
997
1054
|
)
|
998
1055
|
end
|
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/lib/rbs/writer.rb
CHANGED
@@ -285,7 +285,15 @@ module RBS
|
|
285
285
|
else
|
286
286
|
"(#{attr.ivar_name})"
|
287
287
|
end
|
288
|
-
|
288
|
+
|
289
|
+
receiver = case attr.kind
|
290
|
+
when :singleton
|
291
|
+
"self."
|
292
|
+
when :instance
|
293
|
+
""
|
294
|
+
end
|
295
|
+
|
296
|
+
"attr_#{kind} #{receiver}#{attr.name}#{var}: #{attr.type}"
|
289
297
|
end
|
290
298
|
|
291
299
|
def preserve_empty_line(prev, decl)
|
data/schema/members.json
CHANGED
@@ -165,6 +165,10 @@
|
|
165
165
|
"name": {
|
166
166
|
"type": "string"
|
167
167
|
},
|
168
|
+
"kind": {
|
169
|
+
"type": "string",
|
170
|
+
"enum": ["instance", "singleton"]
|
171
|
+
},
|
168
172
|
"type": {
|
169
173
|
"$ref": "types.json"
|
170
174
|
},
|
@@ -194,7 +198,7 @@
|
|
194
198
|
"$ref": "location.json"
|
195
199
|
}
|
196
200
|
},
|
197
|
-
"required": ["member", "name", "ivar_name", "type", "annotations", "comment", "location"]
|
201
|
+
"required": ["member", "name", "ivar_name", "type", "annotations", "kind", "comment", "location"]
|
198
202
|
},
|
199
203
|
"visibility": {
|
200
204
|
"title": "Visibility specifier",
|
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/definition_builder.rbs
CHANGED
@@ -93,5 +93,8 @@ module RBS
|
|
93
93
|
def validate_parameter_variance: (decl: AST::Declarations::Class | AST::Declarations::Module | AST::Declarations::Interface, methods: Hash[Symbol, Definition::Method]) -> void
|
94
94
|
|
95
95
|
def expand_alias: (TypeName) -> Types::t
|
96
|
+
|
97
|
+
type attributes = AST::Members::AttrReader | AST::Members::AttrWriter | AST::Members::AttrAccessor
|
98
|
+
def build_attribute: (type_name: TypeName, definition: Definition, member: attributes, accessibility: Definition::accessibility) -> void
|
96
99
|
end
|
97
100
|
end
|
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/members.rbs
CHANGED
@@ -91,14 +91,17 @@ module RBS
|
|
91
91
|
end
|
92
92
|
|
93
93
|
module Attribute
|
94
|
+
type kind = :instance | :singleton
|
95
|
+
|
94
96
|
attr_reader name: Symbol
|
95
97
|
attr_reader type: Types::t
|
98
|
+
attr_reader kind: kind
|
96
99
|
attr_reader ivar_name: Symbol | false | nil
|
97
100
|
attr_reader annotations: Array[Annotation]
|
98
101
|
attr_reader location: Location?
|
99
102
|
attr_reader comment: Comment?
|
100
103
|
|
101
|
-
def initialize: (name: Symbol, type: Types::t, ivar_name: Symbol | false | nil, annotations: Array[Annotation], location: Location?, comment: Comment?) -> void
|
104
|
+
def initialize: (name: Symbol, type: Types::t, ivar_name: Symbol | false | nil, kind: kind, annotations: Array[Annotation], location: Location?, comment: Comment?) -> void
|
102
105
|
|
103
106
|
include _HashEqual
|
104
107
|
end
|
data/sig/method_types.rbs
CHANGED
@@ -1,24 +1,11 @@
|
|
1
1
|
module RBS
|
2
2
|
class MethodType
|
3
|
-
class Block
|
4
|
-
attr_reader type: Types::Function
|
5
|
-
attr_reader required: bool
|
6
|
-
|
7
|
-
def initialize: (type: Types::Function, required: boolish) -> void
|
8
|
-
|
9
|
-
def ==: (untyped other) -> bool
|
10
|
-
|
11
|
-
def to_json: (*untyped) -> String
|
12
|
-
|
13
|
-
def sub: (Substitution) -> Block
|
14
|
-
end
|
15
|
-
|
16
3
|
attr_reader type_params: Array[Symbol]
|
17
4
|
attr_reader type: Types::Function
|
18
|
-
attr_reader block: Block?
|
5
|
+
attr_reader block: Types::Block?
|
19
6
|
attr_reader location: Location?
|
20
7
|
|
21
|
-
def initialize: (type_params: Array[Symbol], type: Types::Function, block: Block?, location: Location?) -> void
|
8
|
+
def initialize: (type_params: Array[Symbol], type: Types::Function, block: Types::Block?, location: Location?) -> void
|
22
9
|
|
23
10
|
def ==: (untyped other) -> bool
|
24
11
|
|
@@ -26,7 +13,7 @@ module RBS
|
|
26
13
|
|
27
14
|
def sub: (Substitution) -> MethodType
|
28
15
|
|
29
|
-
def update: (?type_params: Array[Symbol], ?type: Types::Function, ?block: Block?, ?location: Location?) -> MethodType
|
16
|
+
def update: (?type_params: Array[Symbol], ?type: Types::Function, ?block: Types::Block?, ?location: Location?) -> MethodType
|
30
17
|
|
31
18
|
def free_variables: (?Set[Symbol] set) -> Set[Symbol]
|
32
19
|
|
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/types.rbs
CHANGED
@@ -334,11 +334,27 @@ module RBS
|
|
334
334
|
def has_keyword?: () -> bool
|
335
335
|
end
|
336
336
|
|
337
|
+
class Block
|
338
|
+
attr_reader type: Types::Function
|
339
|
+
attr_reader required: boolish
|
340
|
+
|
341
|
+
def initialize: (type: Types::Function, required: boolish) -> void
|
342
|
+
|
343
|
+
def ==: (untyped other) -> bool
|
344
|
+
|
345
|
+
def to_json: (*untyped) -> String
|
346
|
+
|
347
|
+
def sub: (Substitution) -> Block
|
348
|
+
|
349
|
+
def map_type: () { (Types::t) -> Types::t } -> Block
|
350
|
+
end
|
351
|
+
|
337
352
|
class Proc
|
338
353
|
attr_reader type: Function
|
354
|
+
attr_reader block: Block?
|
339
355
|
attr_reader location: Location?
|
340
356
|
|
341
|
-
def initialize: (location: Location?, type: Function) -> void
|
357
|
+
def initialize: (location: Location?, type: Function, block: Block?) -> void
|
342
358
|
|
343
359
|
include _TypeBase
|
344
360
|
end
|
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
|