rbs 0.16.0 → 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +1 -1
  3. data/CHANGELOG.md +30 -0
  4. data/README.md +1 -1
  5. data/Rakefile +12 -1
  6. data/core/array.rbs +1 -1
  7. data/core/builtin.rbs +2 -2
  8. data/core/dir.rbs +1 -1
  9. data/core/enumerable.rbs +41 -40
  10. data/core/enumerator.rbs +5 -5
  11. data/core/file.rbs +0 -4
  12. data/core/hash.rbs +9 -11
  13. data/core/io.rbs +1 -1
  14. data/core/object_space.rbs +98 -0
  15. data/core/range.rbs +1 -1
  16. data/core/struct.rbs +1 -1
  17. data/core/time.rbs +0 -12
  18. data/lib/rbs/ast/members.rb +9 -3
  19. data/lib/rbs/definition.rb +9 -4
  20. data/lib/rbs/definition_builder.rb +123 -71
  21. data/lib/rbs/environment.rb +3 -0
  22. data/lib/rbs/environment_loader.rb +1 -1
  23. data/lib/rbs/environment_walker.rb +70 -35
  24. data/lib/rbs/method_type.rb +1 -31
  25. data/lib/rbs/parser.rb +944 -879
  26. data/lib/rbs/parser.y +110 -63
  27. data/lib/rbs/prototype/rb.rb +163 -23
  28. data/lib/rbs/prototype/rbi.rb +5 -5
  29. data/lib/rbs/prototype/runtime.rb +2 -1
  30. data/lib/rbs/test/hook.rb +30 -17
  31. data/lib/rbs/test/type_check.rb +6 -1
  32. data/lib/rbs/types.rb +63 -6
  33. data/lib/rbs/version.rb +1 -1
  34. data/lib/rbs/writer.rb +9 -1
  35. data/schema/members.json +5 -1
  36. data/sig/definition.rbs +8 -3
  37. data/sig/definition_builder.rbs +6 -2
  38. data/sig/members.rbs +4 -1
  39. data/sig/method_types.rbs +3 -16
  40. data/sig/types.rbs +17 -1
  41. data/stdlib/csv/0/csv.rbs +3 -3
  42. data/stdlib/dbm/0/dbm.rbs +1 -3
  43. data/stdlib/monitor/0/monitor.rbs +119 -0
  44. data/stdlib/prime/0/prime.rbs +1 -1
  45. data/stdlib/set/0/set.rbs +10 -10
  46. data/stdlib/singleton/0/singleton.rbs +111 -0
  47. data/stdlib/tsort/0/cyclic.rbs +4 -0
  48. data/stdlib/tsort/0/interfaces.rbs +19 -0
  49. data/stdlib/tsort/0/tsort.rbs +371 -0
  50. data/stdlib/yaml/0/dbm.rbs +221 -0
  51. data/stdlib/yaml/0/store.rbs +53 -0
  52. data/steep/Gemfile.lock +12 -12
  53. metadata +11 -3
@@ -387,19 +387,19 @@ module RBS
387
387
  if block
388
388
  if (type = vars[block])
389
389
  if type.is_a?(Types::Proc)
390
- method_block = MethodType::Block.new(required: true, type: type.type)
390
+ method_block = Types::Block.new(required: true, type: type.type)
391
391
  elsif type.is_a?(Types::Bases::Any)
392
- method_block = MethodType::Block.new(
392
+ method_block = Types::Block.new(
393
393
  required: true,
394
394
  type: Types::Function.empty(Types::Bases::Any.new(location: nil))
395
395
  )
396
396
  # Handle an optional block like `T.nilable(T.proc.void)`.
397
397
  elsif type.is_a?(Types::Optional) && type.type.is_a?(Types::Proc)
398
- method_block = MethodType::Block.new(required: false, type: type.type.type)
398
+ method_block = Types::Block.new(required: false, type: type.type.type)
399
399
  else
400
400
  STDERR.puts "Unexpected block type: #{type}"
401
401
  PP.pp args_node, STDERR
402
- method_block = MethodType::Block.new(
402
+ method_block = Types::Block.new(
403
403
  required: true,
404
404
  type: Types::Function.empty(Types::Bases::Any.new(location: nil))
405
405
  )
@@ -485,7 +485,7 @@ module RBS
485
485
  Types::Tuple.new(types: types, location: nil)
486
486
  else
487
487
  if proc_type?(type_node)
488
- Types::Proc.new(type: method_type(nil, type_node, variables: variables).type, location: nil)
488
+ Types::Proc.new(type: method_type(nil, type_node, variables: variables).type, block: nil, location: nil)
489
489
  else
490
490
  STDERR.puts "Unexpected type_node:"
491
491
  PP.pp type_node, STDERR
@@ -94,6 +94,7 @@ module RBS
94
94
  optional_positionals << Types::Function::Param.new(name: name, type: untyped)
95
95
  when :rest
96
96
  requireds = trailing_positionals
97
+ name = nil if name == :* # For `def f(...) end` syntax
97
98
  rest = Types::Function::Param.new(name: name, type: untyped)
98
99
  when :keyreq
99
100
  required_keywords[name] = Types::Function::Param.new(name: nil, type: untyped)
@@ -102,7 +103,7 @@ module RBS
102
103
  when :keyrest
103
104
  rest_keywords = Types::Function::Param.new(name: nil, type: untyped)
104
105
  when :block
105
- block = MethodType::Block.new(
106
+ block = Types::Block.new(
106
107
  type: Types::Function.empty(untyped).update(rest_positionals: Types::Function::Param.new(name: nil, type: untyped)),
107
108
  required: true
108
109
  )
@@ -27,26 +27,28 @@ module RBS
27
27
  :>> => "rshift",
28
28
  :~ => "tilda"
29
29
  }
30
- def self.alias_names(target)
30
+ def self.alias_names(target, random)
31
+ suffix = "#{RBS::Test.suffix}_#{random}"
32
+
31
33
  case target
32
34
  when *OPERATORS.keys
33
35
  name = OPERATORS[target]
34
36
  [
35
- "#{name}____with__#{Test.suffix}",
36
- "#{name}____without__#{Test.suffix}"
37
+ "#{name}____with__#{suffix}",
38
+ "#{name}____without__#{suffix}"
37
39
  ]
38
40
  else
39
41
  aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
40
42
 
41
43
  [
42
- "#{aliased_target}__with__#{Test.suffix}#{punctuation}",
43
- "#{aliased_target}__without__#{Test.suffix}#{punctuation}"
44
+ "#{aliased_target}__with__#{suffix}#{punctuation}",
45
+ "#{aliased_target}__without__#{suffix}#{punctuation}"
44
46
  ]
45
47
  end
46
48
  end
47
49
 
48
- def self.setup_alias_method_chain(klass, target)
49
- with_method, without_method = alias_names(target)
50
+ def self.setup_alias_method_chain(klass, target, random:)
51
+ with_method, without_method = alias_names(target, random)
50
52
 
51
53
  RBS.logger.debug "alias name: #{target}, #{with_method}, #{without_method}"
52
54
 
@@ -65,12 +67,12 @@ module RBS
65
67
  end
66
68
  end
67
69
 
68
- def self.hook_method_source(prefix, method_name, key)
69
- with_name, without_name = alias_names(method_name)
70
+ def self.hook_method_source(prefix, method_name, key, random:)
71
+ with_name, without_name = alias_names(method_name, random)
70
72
  full_method_name = "#{prefix}#{method_name}"
71
73
 
72
74
  [__LINE__ + 1, <<RUBY]
73
- def #{with_name}(*args)
75
+ def #{with_name}(*args, &block)
74
76
  ::RBS.logger.debug { "#{full_method_name} with arguments: [" + args.map(&:inspect).join(", ") + "]" }
75
77
 
76
78
  begin
@@ -78,11 +80,18 @@ def #{with_name}(*args)
78
80
  block_calls = []
79
81
 
80
82
  if block_given?
81
- result = __send__(:"#{without_name}", *args) do |*block_args|
83
+ receiver = self
84
+
85
+ wrapped_block = proc do |*block_args|
82
86
  return_from_block = false
83
87
 
84
88
  begin
85
- block_result = yield(*block_args)
89
+ block_result = if receiver.equal?(self)
90
+ yield(*block_args)
91
+ else
92
+ instance_exec(*block_args, &block)
93
+ end
94
+
86
95
  return_from_block = true
87
96
  ensure
88
97
  exn = $!
@@ -109,7 +118,9 @@ def #{with_name}(*args)
109
118
  end
110
119
 
111
120
  block_result
112
- end
121
+ end.ruby2_keywords
122
+
123
+ result = __send__(:"#{without_name}", *args, &wrapped_block)
113
124
  else
114
125
  result = __send__(:"#{without_name}", *args)
115
126
  end
@@ -154,17 +165,19 @@ RUBY
154
165
  end
155
166
 
156
167
  def self.hook_instance_method(klass, method, key:)
157
- line, source = hook_method_source("#{klass}#", method, key)
168
+ random = SecureRandom.hex(4)
169
+ line, source = hook_method_source("#{klass}#", method, key, random: random)
158
170
 
159
171
  klass.module_eval(source, __FILE__, line)
160
- setup_alias_method_chain klass, method
172
+ setup_alias_method_chain klass, method, random: random
161
173
  end
162
174
 
163
175
  def self.hook_singleton_method(klass, method, key:)
164
- line, source = hook_method_source("#{klass}.",method, key)
176
+ random = SecureRandom.hex(4)
177
+ line, source = hook_method_source("#{klass}.",method, key, random: random)
165
178
 
166
179
  klass.singleton_class.module_eval(source, __FILE__, line)
167
- setup_alias_method_chain klass.singleton_class, method
180
+ setup_alias_method_chain klass.singleton_class, method, random: random
168
181
  end
169
182
  end
170
183
  end
@@ -288,7 +288,12 @@ module RBS
288
288
  end
289
289
  when Types::ClassSingleton
290
290
  klass = get_class(type.name) or return false
291
- val == klass
291
+ singleton_class = begin
292
+ klass.singleton_class
293
+ rescue TypeError
294
+ return false
295
+ end
296
+ val.is_a?(singleton_class)
292
297
  when Types::Interface
293
298
  methods = Set.new(Test.call(val, METHODS))
294
299
  if (definition = builder.build_interface(type.name))
@@ -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
- { class: :proc, type: type, location: location }.to_json(*a)
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
- "^(#{type.param_to_s}) -> #{type.return_to_s}".lstrip
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
@@ -1,3 +1,3 @@
1
1
  module RBS
2
- VERSION = "0.16.0"
2
+ VERSION = "0.20.0"
3
3
  end
@@ -285,7 +285,15 @@ module RBS
285
285
  else
286
286
  "(#{attr.ivar_name})"
287
287
  end
288
- "attr_#{kind} #{attr.name}#{var}: #{attr.type}"
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)
@@ -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",
@@ -21,13 +21,13 @@ module RBS
21
21
  attr_reader defined_in: TypeName
22
22
  attr_reader implemented_in: TypeName?
23
23
 
24
- def initialize: (type: MethodType, member: method_member, defined_in: TypeName?, implemented_in: TypeName?) -> void
24
+ def initialize: (type: MethodType, member: method_member, defined_in: TypeName, implemented_in: TypeName?) -> void
25
25
 
26
26
  def comment: () -> AST::Comment?
27
27
 
28
28
  def annotations: () -> Array[AST::Annotation]
29
29
 
30
- def update: (?type: MethodType, ?member: method_member, ?defined_in: TypeName?, ?implemented_in: TypeName?) -> TypeDef
30
+ def update: (?type: MethodType, ?member: method_member, ?defined_in: TypeName, ?implemented_in: TypeName?) -> TypeDef
31
31
 
32
32
  def overload?: () -> bool
33
33
  end
@@ -42,8 +42,13 @@ module RBS
42
42
  attr_reader comments: Array[AST::Comment]
43
43
  attr_reader annotations: Array[AST::Annotation]
44
44
  attr_reader members: Array[method_member]
45
+ attr_reader alias_of: Method?
45
46
 
46
- def initialize: (super_method: Method?, defs: Array[TypeDef], accessibility: accessibility, ?annotations: Array[AST::Annotation]) -> void
47
+ def initialize: (super_method: Method?,
48
+ defs: Array[TypeDef],
49
+ accessibility: accessibility,
50
+ alias_of: Method?,
51
+ ?annotations: Array[AST::Annotation]) -> void
47
52
 
48
53
  def public?: () -> bool
49
54
 
@@ -62,7 +62,7 @@ module RBS
62
62
  def ensure_namespace!: (Namespace, location: Location?) -> void
63
63
 
64
64
  def build_singleton: (TypeName) -> Definition
65
-
65
+
66
66
  def build_instance: (TypeName) -> Definition
67
67
 
68
68
  def build_interface: (TypeName) -> Definition
@@ -71,11 +71,12 @@ module RBS
71
71
 
72
72
  def build_one_singleton: (TypeName) -> Definition
73
73
 
74
+ type ancestors = Definition::InstanceAncestors | Definition::SingletonAncestors | nil
74
75
  def merge_definitions: (TypeName,
75
76
  Array[[Definition::Ancestor::t, Definition]],
76
77
  entry: Environment::ModuleEntry | Environment::ClassEntry,
77
78
  self_type: Definition::self_type,
78
- ancestors: Array[Definition::Ancestor::t]) -> Definition
79
+ ancestors: ancestors) -> Definition
79
80
 
80
81
  type method_kind = :instance | :singleton
81
82
  def merge_method: (TypeName, Hash[Symbol, Definition::Method], Symbol, Definition::Method, Substitution, kind: method_kind) -> void
@@ -92,5 +93,8 @@ module RBS
92
93
  def validate_parameter_variance: (decl: AST::Declarations::Class | AST::Declarations::Module | AST::Declarations::Interface, methods: Hash[Symbol, Definition::Method]) -> void
93
94
 
94
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
95
99
  end
96
100
  end
@@ -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
@@ -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