rbs 2.7.0 → 2.8.0.pre.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d5774c0ae32533d1da69481ae4b413817580fd9974b445a67bef1faf4ff48080
4
- data.tar.gz: 3f4552b3a91d2fc233f110b8682b73674454163a540d271c9f355daf6e61b5d3
3
+ metadata.gz: a1d6bcfbb96db1bd762270824620e4a430057521398fdef7d8543cceaaaab127
4
+ data.tar.gz: 4616fee00017d88cb942fa34f25dee2bd1959ba83bf3f8eedf7f57770792d2e0
5
5
  SHA512:
6
- metadata.gz: '0827ff2d63c104b99b07b5319f581b559b6dd7b6e9a26ae2f65d2fc5f8b9c435fff19690b9efe1dfed4c5d220c61c4afdb74203a2275b27bd95a934fbe467c16'
7
- data.tar.gz: 7584c2471066032562ca5c3eb39dc8880e764f0fa880fcb9d1ee5e5b56b29fad9d2991b570b17ccf8b9e1f9ecf395c4719609d176dc2058fce6bfac03455d79f
6
+ metadata.gz: 9bfb3f1cb6ed463fbc9d78181b6fdd683bbb476adfdbda4ef7a1009d8c225ee96f7f5d958dbba3d2f5b461f2253ad0d27e68072653efde251886550cf64973c3
7
+ data.tar.gz: bb8b7a2984b4211d8bbb19d213b999f78caa9e676fef3584da29b49a18639362f2884233337e1c5aedad01ce495055085ae080df81f696ce135de1220638d34a
data/CHANGELOG.md CHANGED
@@ -2,6 +2,35 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 2.8.0.pre.1 (2022-11-17)
6
+
7
+ ### Signature updates
8
+
9
+ * `IO` ([#1132](https://github.com/ruby/rbs/pull/1132))
10
+ * `IO::Buffer` ([#1137](https://github.com/ruby/rbs/pull/1137))
11
+ * `IPAddr` ([#1131](https://github.com/ruby/rbs/pull/1131), [#1151](https://github.com/ruby/rbs/pull/1151))
12
+ * `Socket` ([#1133](https://github.com/ruby/rbs/pull/1133), [#1134](https://github.com/ruby/rbs/pull/1134), [#1151](https://github.com/ruby/rbs/pull/1151))
13
+ * `Yaml` ([#1141](https://github.com/ruby/rbs/pull/1141))
14
+
15
+ ### Library changes
16
+
17
+ * Make type/method-type parser more flexible about input position ([#1140](https://github.com/ruby/rbs/pull/1140))
18
+ * Raise an error if a class definition inherits a module ([#1152](https://github.com/ruby/rbs/pull/1152))
19
+ * Fix SEGV when parse with invalid content ([#1146](https://github.com/ruby/rbs/pull/1146))
20
+
21
+ #### rbs collection
22
+
23
+ * Support to call collection command in child dir ([#1025](https://github.com/ruby/rbs/pull/1025), [#1135](https://github.com/ruby/rbs/pull/1135))
24
+
25
+ ### Miscellaneous
26
+
27
+ * Remove `rubygems` from `rbs`’s manifest ([#1150](https://github.com/ruby/rbs/pull/1150))
28
+ * Use `untyped` instead of `any` in `syntax.md` ([#1147](https://github.com/ruby/rbs/pull/1147))
29
+ * Fix typo and grammatical mistakes in "Generics" section of `syntax.md` ([#1127](https://github.com/ruby/rbs/pull/1127))
30
+ * Add a doc that describes tools related to RBS ([#1125](https://github.com/ruby/rbs/pull/1125))
31
+ * Add self-type-bindings to `syntax.md` ([#1123](https://github.com/ruby/rbs/pull/1123))
32
+ * Add documentation for `...` in `syntax.md` ([#1120](https://github.com/ruby/rbs/pull/1120))
33
+
5
34
  ## 2.7.0 (2022-10-07)
6
35
 
7
36
  ### Signature updates
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rbs (2.7.0)
4
+ rbs (2.8.0.pre.1)
5
5
 
6
6
  PATH
7
7
  remote: test/assets/test-gem
@@ -47,32 +47,32 @@ GEM
47
47
  rake
48
48
  rdoc (6.4.0)
49
49
  psych (>= 4.0.0)
50
- regexp_parser (2.5.0)
50
+ regexp_parser (2.6.0)
51
51
  rexml (3.2.5)
52
- rspec (3.11.0)
53
- rspec-core (~> 3.11.0)
54
- rspec-expectations (~> 3.11.0)
55
- rspec-mocks (~> 3.11.0)
56
- rspec-core (3.11.0)
57
- rspec-support (~> 3.11.0)
58
- rspec-expectations (3.11.0)
52
+ rspec (3.12.0)
53
+ rspec-core (~> 3.12.0)
54
+ rspec-expectations (~> 3.12.0)
55
+ rspec-mocks (~> 3.12.0)
56
+ rspec-core (3.12.0)
57
+ rspec-support (~> 3.12.0)
58
+ rspec-expectations (3.12.0)
59
59
  diff-lcs (>= 1.2.0, < 2.0)
60
- rspec-support (~> 3.11.0)
61
- rspec-mocks (3.11.1)
60
+ rspec-support (~> 3.12.0)
61
+ rspec-mocks (3.12.0)
62
62
  diff-lcs (>= 1.2.0, < 2.0)
63
- rspec-support (~> 3.11.0)
64
- rspec-support (3.11.0)
65
- rubocop (1.36.0)
63
+ rspec-support (~> 3.12.0)
64
+ rspec-support (3.12.0)
65
+ rubocop (1.38.0)
66
66
  json (~> 2.3)
67
67
  parallel (~> 1.10)
68
68
  parser (>= 3.1.2.1)
69
69
  rainbow (>= 2.2.2, < 4.0)
70
70
  regexp_parser (>= 1.8, < 3.0)
71
71
  rexml (>= 3.2.5, < 4.0)
72
- rubocop-ast (>= 1.20.1, < 2.0)
72
+ rubocop-ast (>= 1.23.0, < 2.0)
73
73
  ruby-progressbar (~> 1.7)
74
74
  unicode-display_width (>= 1.4.0, < 3.0)
75
- rubocop-ast (1.21.0)
75
+ rubocop-ast (1.23.0)
76
76
  parser (>= 3.1.1.0)
77
77
  rubocop-rubycw (0.1.6)
78
78
  rubocop (~> 1.0)
@@ -80,13 +80,13 @@ GEM
80
80
  rake (>= 0.8.1)
81
81
  ruby-progressbar (1.11.0)
82
82
  singleton (0.1.1)
83
- stackprof (0.2.21)
83
+ stackprof (0.2.22)
84
84
  stringio (3.0.2)
85
85
  strong_json (2.1.2)
86
86
  tempfile (0.1.2)
87
87
  test-unit (3.5.5)
88
88
  power_assert
89
- unicode-display_width (2.2.0)
89
+ unicode-display_width (2.3.0)
90
90
 
91
91
  PLATFORMS
92
92
  ruby
data/Steepfile CHANGED
@@ -9,14 +9,12 @@ target :lib do
9
9
  "lib/rbs/test.rb"
10
10
  )
11
11
 
12
- library "set", "pathname", "json", "logger", "monitor", "tsort", "uri", 'yaml', 'dbm', 'pstore', 'singleton', 'shellwords', 'fileutils', 'find', 'digest'
12
+ library "set", "pathname", "json", "logger", "monitor", "tsort", "uri", 'dbm', 'pstore', 'singleton', 'shellwords', 'fileutils', 'find', 'digest'
13
+ signature 'stdlib/yaml/0'
13
14
  signature "stdlib/strscan/0/"
14
15
  signature "stdlib/optparse/0/"
15
16
  signature "stdlib/rdoc/0/"
16
17
 
17
- # Please remove the following line after releasing #1107
18
- signature "core/rubygems/"
19
-
20
18
  configure_code_diagnostics do |config|
21
19
  config[D::Ruby::MethodDefinitionMissing] = :hint
22
20
  config[D::Ruby::ElseOnExhaustiveCase] = :hint
data/core/io/buffer.rbs CHANGED
@@ -706,5 +706,20 @@ class IO
706
706
  PRIVATE: Integer
707
707
 
708
708
  READONLY: Integer
709
+
710
+ class LockedError < RuntimeError
711
+ end
712
+
713
+ class AllocationError < RuntimeError
714
+ end
715
+
716
+ class AccessError < RuntimeError
717
+ end
718
+
719
+ class InvalidatedError < RuntimeError
720
+ end
721
+
722
+ class MaskError < ArgumentError
723
+ end
709
724
  end
710
725
  end
data/core/io.rbs CHANGED
@@ -2984,6 +2984,12 @@ IO::TRUNC: Integer
2984
2984
 
2985
2985
  IO::WRONLY: Integer
2986
2986
 
2987
+ IO::READABLE: Integer
2988
+
2989
+ IO::WRITABLE: Integer
2990
+
2991
+ IO::PRIORITY: Integer
2992
+
2987
2993
  # <!-- rdoc-file=io.c -->
2988
2994
  # exception to wait for reading by EAGAIN. see IO.select.
2989
2995
  #
data/docs/syntax.md CHANGED
@@ -3,18 +3,17 @@
3
3
  ## Types
4
4
 
5
5
  ```markdown
6
- _type_ ::= _class-name_ _type-arguments_ (Class instance type)
7
- | _interface-name_ _type-arguments_ (Interface type)
8
- | _alias-name_ _type-arguments_ (Alias type)
9
- | `singleton(` _class-name_ `)` (Class singleton type)
10
- | _literal_ (Literal type)
11
- | _type_ `|` _type_ (Union type)
12
- | _type_ `&` _type_ (Intersection type)
13
- | _type_ `?` (Optional type)
14
- | `{` _record-name_ `:` _type_ `,` etc. `}` (Record type)
15
- | `[]` | `[` _type_ `,` etc. `]` (Tuples)
16
- | _type-variable_ (Type variables)
17
- | `^(` _parameters_ `) ->` _type_ (Proc type)
6
+ _type_ ::= _class-name_ _type-arguments_ (Class instance type)
7
+ | _interface-name_ _type-arguments_ (Interface type)
8
+ | _alias-name_ _type-arguments_ (Alias type)
9
+ | `singleton(` _class-name_ `)` (Class singleton type)
10
+ | _literal_ (Literal type)
11
+ | _type_ `|` _type_ (Union type)
12
+ | _type_ `&` _type_ (Intersection type)
13
+ | _type_ `?` (Optional type)
14
+ | `{` _record-name_ `:` _type_ `,` etc. `}` (Record type)
15
+ | `[]` | `[` _type_ `,` etc. `]` (Tuples)
16
+ | _type-variable_ (Type variables)
18
17
  | `self`
19
18
  | `instance`
20
19
  | `class`
@@ -24,6 +23,7 @@ _type_ ::= _class-name_ _type-arguments_ (Class instance type)
24
23
  | `top`
25
24
  | `bot`
26
25
  | `void`
26
+ | _proc_ (Proc type)
27
27
 
28
28
  _class-name_ ::= _namespace_ /[A-Z]\w*/
29
29
  _interface-name_ ::= _namespace_ /_[A-Z]\w*/
@@ -43,6 +43,8 @@ _literal_ ::= _string-literal_
43
43
  | _integer-literal_
44
44
  | `true`
45
45
  | `false`
46
+
47
+ _proc_ ::= _parameters?_ _self-type-binding?_ _block?_ `->` _type_
46
48
  ```
47
49
 
48
50
  ### Class instance type
@@ -164,15 +166,6 @@ class Ref[T] # Object is scoped in the class declaration.
164
166
  end
165
167
  ```
166
168
 
167
- ### Proc type
168
-
169
- Proc type denotes type of procedures, `Proc` instances.
170
-
171
- ```
172
- ^(Integer) -> String # A procedure with an `Integer` parameter and returns `String`
173
- ^(?String, size: Integer) -> bool # A procedure with `String` optional parameter, `size` keyword of `Integer`, and returns `bool`
174
- ```
175
-
176
169
  ### Base types
177
170
 
178
171
  `self` denotes the type of receiver. The type is used to model the open recursion via `self`.
@@ -221,14 +214,28 @@ They are all equivalent for the type system; they are all _top type_.
221
214
 
222
215
  `void` tells developers a hint that _the value should not be used_. `boolish` implies the value is used as a truth value. `top` is anything else.
223
216
 
224
- ## Method Types
217
+ ### Proc type
218
+
219
+ Proc type denotes type of procedures, `Proc` instances.
220
+
221
+ ```
222
+ ^(Integer) -> String # A procedure with an `Integer` parameter and returns `String`
223
+ ^(?String, size: Integer) -> bool # A procedure with `String` optional parameter, `size` keyword of `Integer`, and returns `bool`
224
+ ```
225
+
226
+ See the next section for details.
227
+
228
+ ## Method Types and Proc Types
225
229
 
226
230
  ```markdown
227
- _method-type_ ::= `(` _parameters_ `) ->` _type_ # Method without block
228
- | `(` _parameters_ `) { (` _parameters_ `) -> ` _type_ `} ->` _type_ # Method with required block
229
- | `(` _parameters_ `) ?{ (` _parameters_ `) -> ` _type_ `} ->` _type_ # Method with optional block
231
+ _method-type_ ::= _parameters?_ _block?_ `->` _type_ # Method type
232
+
233
+ _proc_ ::= `^` _parameters?_ _self-type-binding?_ _block?_ `->` _type_ # Proc type
230
234
 
231
- _parameters_ ::= _required-positionals_ _optional-positionals_ _rest-positional_ _trailing-positionals_ _keywords_
235
+ _parameters?_ ::= (Empty)
236
+ | _parameters_ (Parameters)
237
+
238
+ _parameters_ ::= `(` _required-positionals_ _optional-positionals_ _rest-positional_ _trailing-positionals_ _keywords_ `)`
232
239
 
233
240
  _parameter_ ::= _type_ _var-name_ # Parameter with var name
234
241
  | _type_ # Parameter without var name
@@ -243,6 +250,13 @@ _keywords_ ::= # Empty
243
250
  | `?` _keyword_ `:` _parameter_ `,` _keywords_ # Optional keyword
244
251
 
245
252
  _var-name_ ::= /[a-z]\w*/
253
+
254
+ _self-type-binding?_ = (Empty)
255
+ | `[` `self` `:` _type_ `]` (Self type binding)
256
+
257
+ _block?_ = (No block)
258
+ | `{` _parameters_ _self-type-binding?_ `->` _type_ `}` (Block)
259
+ | `?` `{` _parameters_ _self-type-binding?_ `->` _type_ `}` (Optional block)
246
260
  ```
247
261
 
248
262
  ### Parameters
@@ -250,7 +264,7 @@ _var-name_ ::= /[a-z]\w*/
250
264
  A parameter can be a type or a pair of type and variable name.
251
265
  Variable name can be used for documentation.
252
266
 
253
- ### Examples
267
+ #### Examples
254
268
 
255
269
  ```
256
270
  # Two required positional `Integer` parameters, and returns `String`
@@ -269,6 +283,29 @@ Variable name can be used for documentation.
269
283
  (size: Integer sz, ?name: String, ?created_at: Time?) -> void
270
284
  ```
271
285
 
286
+ ### Self type binding
287
+
288
+ Self type binding represents the type of methods that uses `#instance_eval`, which replaces the value of `self` inside blocks.
289
+
290
+ ```ruby
291
+ 123.instance_eval do
292
+ self + 1 # self is `123` here
293
+ end
294
+ ```
295
+
296
+ Proc types and blocks can have self type bindings.
297
+
298
+ ```rbs
299
+ ^(Integer) [self: String] -> void # Proc type with self type binding
300
+ ^(Integer) [self: String] { (Symbol) [self: bool] -> void } -> void # Proc type with self type binding of `String` and a block with self type binding of `bool`
301
+ ```
302
+
303
+ Method type can have blocks with self type bindings.
304
+
305
+ ```rbs
306
+ () { (Integer) [self: String] -> void } -> void # A method type with block with self type binding
307
+ ```
308
+
272
309
  ## Members
273
310
 
274
311
  ```markdown
@@ -349,6 +386,14 @@ def +: (Float) -> Float
349
386
  | (Numeric) -> Numeric
350
387
  ```
351
388
 
389
+ Overloaded method can have `...` to overload an existing method. It is useful for monkey-patching.
390
+
391
+ ```
392
+ def +: (Float) -> Float
393
+ def +: (BigDecimal) -> BigDecimal
394
+ | ...
395
+ ```
396
+
352
397
  You need extra parentheses on return type to avoid ambiguity.
353
398
 
354
399
  ```
@@ -516,7 +561,7 @@ Interface declaration can have parameters but allows only a few of the members.
516
561
  ```
517
562
  interface _Hashing
518
563
  def hash: () -> Integer
519
- def eql?: (any) -> bool
564
+ def eql?: (untyped) -> bool
520
565
  end
521
566
  ```
522
567
 
@@ -574,8 +619,8 @@ _generics-bound_ ::= (No type bound)
574
619
  | `<` _bound-type_ (The generics parameter is bounded)
575
620
 
576
621
  _bound-type_ ::= _class-name_ _type-arguments_ (Class instance type)
577
- | _interface-name_ _type-arguments_ (Interface type)
578
- | `singleton(` _class-name_ `)` (Class singleton type)
622
+ | _interface-name_ _type-arguments_ (Interface type)
623
+ | `singleton(` _class-name_ `)` (Class singleton type)
579
624
 
580
625
  _generics-variance_ ::= (Invariant)
581
626
  | `out` (Covariant)
@@ -607,8 +652,8 @@ class Array[out T]
607
652
  end
608
653
  ```
609
654
 
610
- There's a limitation with this is for mutable objects (like arrays): a mutation could invalidate this.
611
- If an array of `String` is passed to a method as an array of `Objects`, and that method adds an Integer to the array, the promise is broken.
655
+ There's a limitation with this for mutable objects (like arrays): a mutation could invalidate this.
656
+ If an `Array` of `String` is passed to a method as an `Array` of `Object`, and that method adds an `Integer` to the `Array`, the promise is broken.
612
657
 
613
658
  In those cases, one must use the `unchecked` keyword:
614
659
 
data/docs/tools.md ADDED
@@ -0,0 +1,16 @@
1
+ # Tools
2
+
3
+ This documentation describes major tools related to RBS. They are listed alphabetically.
4
+
5
+ ## Type Checkers
6
+
7
+ * [Steep](https://github.com/soutaro/steep) is a static type checker based on RBS. You can use it as a language server integrated with an editor or IDE and run it from the command line.
8
+ * [TypeProf](https://github.com/ruby/typeprof)
9
+
10
+ ## Editor integrations
11
+
12
+ * Emacs: [rbs-mode](https://github.com/ybiquitous/rbs-mode)
13
+ * RubyMine: [It supports RBS by default](https://www.jetbrains.com/help/ruby/rbs.html)
14
+ * Sublime Text: [sublime-rbs-plugin](https://github.com/soutaro/sublime-rbs-plugin)
15
+ * Vim: [rbs.vim](https://github.com/pocke/rbs.vim)
16
+ * Visual Studio Code: [vscode-rbs-syntax](https://github.com/soutaro/vscode-rbs-syntax)
@@ -119,6 +119,8 @@ typedef struct {
119
119
  * */
120
120
  typedef struct {
121
121
  VALUE string;
122
+ int start_pos; /* The character position that defines the start of the input */
123
+ int end_pos; /* The character position that defines the end of the input */
122
124
  position current; /* The current position */
123
125
  position start; /* The start position of the current token */
124
126
  bool first_token_of_line; /* This flag is used for tLINECOMMENT */
@@ -100,9 +100,14 @@ int token_bytes(token tok) {
100
100
  }
101
101
 
102
102
  unsigned int peek(lexstate *state) {
103
- unsigned int c = rb_enc_mbc_to_codepoint(RSTRING_PTR(state->string) + state->current.byte_pos, RSTRING_END(state->string), rb_enc_get(state->string));
104
- state->last_char = c;
105
- return c;
103
+ if (state->current.char_pos == state->end_pos) {
104
+ state->last_char = '\0';
105
+ return 0;
106
+ } else {
107
+ unsigned int c = rb_enc_mbc_to_codepoint(RSTRING_PTR(state->string) + state->current.byte_pos, RSTRING_END(state->string), rb_enc_get(state->string));
108
+ state->last_char = c;
109
+ return c;
110
+ }
106
111
  }
107
112
 
108
113
  token next_token(lexstate *state, enum TokenType type) {
@@ -137,6 +142,7 @@ void skip(lexstate *state) {
137
142
 
138
143
  void skipn(lexstate *state, size_t size) {
139
144
  for (size_t i = 0; i < size; i ++) {
145
+ peek(state);
140
146
  skip(state);
141
147
  }
142
148
  }
@@ -2502,12 +2502,19 @@ VALUE parse_signature(parserstate *state) {
2502
2502
  }
2503
2503
 
2504
2504
  static VALUE
2505
- rbsparser_parse_type(VALUE self, VALUE buffer, VALUE line, VALUE column, VALUE variables)
2505
+ rbsparser_parse_type(VALUE self, VALUE buffer, VALUE start_pos, VALUE end_pos, VALUE variables, VALUE requires_eof)
2506
2506
  {
2507
- parserstate *parser = alloc_parser(buffer, FIX2INT(line), FIX2INT(column), variables);
2507
+ parserstate *parser = alloc_parser(buffer, FIX2INT(start_pos), FIX2INT(end_pos), variables);
2508
+
2509
+ if (parser->next_token.type == pEOF) {
2510
+ return Qnil;
2511
+ }
2508
2512
 
2509
2513
  VALUE type = parse_type(parser);
2510
- parser_advance_assert(parser, pEOF);
2514
+
2515
+ if (RTEST(requires_eof)) {
2516
+ parser_advance_assert(parser, pEOF);
2517
+ }
2511
2518
 
2512
2519
  free_parser(parser);
2513
2520
 
@@ -2515,19 +2522,29 @@ rbsparser_parse_type(VALUE self, VALUE buffer, VALUE line, VALUE column, VALUE v
2515
2522
  }
2516
2523
 
2517
2524
  static VALUE
2518
- rbsparser_parse_method_type(VALUE self, VALUE buffer, VALUE line, VALUE column, VALUE variables)
2525
+ rbsparser_parse_method_type(VALUE self, VALUE buffer, VALUE start_pos, VALUE end_pos, VALUE variables, VALUE requires_eof)
2519
2526
  {
2520
- parserstate *parser = alloc_parser(buffer, FIX2INT(line), FIX2INT(column), variables);
2527
+ parserstate *parser = alloc_parser(buffer, FIX2INT(start_pos), FIX2INT(end_pos), variables);
2528
+
2529
+ if (parser->next_token.type == pEOF) {
2530
+ return Qnil;
2531
+ }
2532
+
2521
2533
  VALUE method_type = parse_method_type(parser);
2522
- free(parser);
2534
+
2535
+ if (RTEST(requires_eof)) {
2536
+ parser_advance_assert(parser, pEOF);
2537
+ }
2538
+
2539
+ free_parser(parser);
2523
2540
 
2524
2541
  return method_type;
2525
2542
  }
2526
2543
 
2527
2544
  static VALUE
2528
- rbsparser_parse_signature(VALUE self, VALUE buffer, VALUE line, VALUE column)
2545
+ rbsparser_parse_signature(VALUE self, VALUE buffer, VALUE end_pos)
2529
2546
  {
2530
- parserstate *parser = alloc_parser(buffer, FIX2INT(line), FIX2INT(column), Qnil);
2547
+ parserstate *parser = alloc_parser(buffer, 0, FIX2INT(end_pos), Qnil);
2531
2548
  VALUE signature = parse_signature(parser);
2532
2549
  free_parser(parser);
2533
2550
 
@@ -2536,7 +2553,7 @@ rbsparser_parse_signature(VALUE self, VALUE buffer, VALUE line, VALUE column)
2536
2553
 
2537
2554
  void rbs__init_parser(void) {
2538
2555
  RBS_Parser = rb_define_class_under(RBS, "Parser", rb_cObject);
2539
- rb_define_singleton_method(RBS_Parser, "_parse_type", rbsparser_parse_type, 4);
2540
- rb_define_singleton_method(RBS_Parser, "_parse_method_type", rbsparser_parse_method_type, 4);
2541
- rb_define_singleton_method(RBS_Parser, "_parse_signature", rbsparser_parse_signature, 3);
2556
+ rb_define_singleton_method(RBS_Parser, "_parse_type", rbsparser_parse_type, 5);
2557
+ rb_define_singleton_method(RBS_Parser, "_parse_method_type", rbsparser_parse_method_type, 5);
2558
+ rb_define_singleton_method(RBS_Parser, "_parse_signature", rbsparser_parse_signature, 2);
2542
2559
  }
@@ -272,13 +272,17 @@ VALUE comment_to_ruby(comment *com, VALUE buffer) {
272
272
  );
273
273
  }
274
274
 
275
- parserstate *alloc_parser(VALUE buffer, int line, int column, VALUE variables) {
275
+ parserstate *alloc_parser(VALUE buffer, int start_pos, int end_pos, VALUE variables) {
276
276
  VALUE string = rb_funcall(buffer, rb_intern("content"), 0);
277
277
 
278
+ StringValue(string);
279
+
278
280
  lexstate *lexer = calloc(1, sizeof(lexstate));
279
281
  lexer->string = string;
280
- lexer->current.line = line;
281
- lexer->current.column = column;
282
+ lexer->current.line = 1;
283
+ lexer->start_pos = start_pos;
284
+ lexer->end_pos = end_pos;
285
+ skipn(lexer, start_pos);
282
286
  lexer->start = lexer->current;
283
287
  lexer->first_token_of_line = lexer->current.column == 0;
284
288
 
@@ -101,7 +101,7 @@ bool parser_typevar_member(parserstate *state, ID id);
101
101
  * alloc_parser(buffer, 3, 5, Qnil) // New parserstate without variables
102
102
  * ```
103
103
  * */
104
- parserstate *alloc_parser(VALUE buffer, int line, int column, VALUE variables);
104
+ parserstate *alloc_parser(VALUE buffer, int start_pos, int end_pos, VALUE variables);
105
105
  void free_parser(parserstate *parser);
106
106
  /**
107
107
  * Advance one token.
data/lib/rbs/cli.rb CHANGED
@@ -19,7 +19,7 @@ module RBS
19
19
 
20
20
  @libs = []
21
21
  @dirs = []
22
- @config_path = Collection::Config::PATH
22
+ @config_path = Collection::Config.find_config_path || Collection::Config::PATH
23
23
  end
24
24
 
25
25
  def loader
@@ -1034,16 +1034,17 @@ EOB
1034
1034
  opts.order args.drop(1), into: params
1035
1035
  config_path = options.config_path or raise
1036
1036
  lock_path = Collection::Config.to_lockfile_path(config_path)
1037
+ gemfile_lock_path = Bundler.default_lockfile
1037
1038
 
1038
1039
  case args[0]
1039
1040
  when 'install'
1040
1041
  unless params[:frozen]
1041
- Collection::Config.generate_lockfile(config_path: config_path, gemfile_lock_path: Pathname('./Gemfile.lock'))
1042
+ Collection::Config.generate_lockfile(config_path: config_path, gemfile_lock_path: gemfile_lock_path)
1042
1043
  end
1043
1044
  Collection::Installer.new(lockfile_path: lock_path, stdout: stdout).install_from_lockfile
1044
1045
  when 'update'
1045
1046
  # TODO: Be aware of argv to update only specified gem
1046
- Collection::Config.generate_lockfile(config_path: config_path, gemfile_lock_path: Pathname('./Gemfile.lock'), with_lockfile: false)
1047
+ Collection::Config.generate_lockfile(config_path: config_path, gemfile_lock_path: gemfile_lock_path, with_lockfile: false)
1047
1048
  Collection::Installer.new(lockfile_path: lock_path, stdout: stdout).install_from_lockfile
1048
1049
  when 'init'
1049
1050
  if config_path.exist?
@@ -2,10 +2,24 @@
2
2
 
3
3
  module RBS
4
4
  module Collection
5
-
6
- # This class represent the configration file.
7
5
  class Config
8
6
  class LockfileGenerator
7
+ class GemfileLockMismatchError < StandardError
8
+ def initialize(expected:, actual:)
9
+ @expected = expected
10
+ @actual = actual
11
+ end
12
+
13
+ def message
14
+ <<~MESSAGE
15
+ RBS Collection loads a different Gemfile.lock from before.
16
+ The Gemfile.lock must be the same as that is recorded in rbs_collection.lock.yaml.
17
+ Expected Gemfile.lock: #{@expected}
18
+ Actual Gemfile.lock: #{@actual}
19
+ MESSAGE
20
+ end
21
+ end
22
+
9
23
  attr_reader :config, :lock, :gemfile_lock, :lock_path
10
24
 
11
25
  def self.generate(config_path:, gemfile_lock_path:, with_lockfile: true)
@@ -18,6 +32,10 @@ module RBS
18
32
  @lock = Config.from_path(lock_path) if lock_path.exist? && with_lockfile
19
33
  @gemfile_lock = Bundler::LockfileParser.new(gemfile_lock_path.read)
20
34
  @gem_queue = []
35
+
36
+ validate_gemfile_lock_path!(lock: lock, gemfile_lock_path: gemfile_lock_path)
37
+
38
+ config.gemfile_lock_path = gemfile_lock_path
21
39
  end
22
40
 
23
41
  def generate
@@ -38,6 +56,14 @@ module RBS
38
56
  config
39
57
  end
40
58
 
59
+ private def validate_gemfile_lock_path!(lock:, gemfile_lock_path:)
60
+ return unless lock
61
+ return unless lock.gemfile_lock_path
62
+ return if lock.gemfile_lock_path == gemfile_lock_path
63
+
64
+ raise GemfileLockMismatchError.new(expected: lock.gemfile_lock_path, actual: gemfile_lock_path)
65
+ end
66
+
41
67
  private def assign_gem(name:, version:)
42
68
  # @type var locked: gem_entry?
43
69
  locked = lock&.gem(name)
@@ -16,6 +16,17 @@ module RBS
16
16
 
17
17
  PATH = Pathname('rbs_collection.yaml')
18
18
 
19
+ def self.find_config_path
20
+ current = Pathname.pwd
21
+
22
+ loop do
23
+ config_path = current.join(PATH)
24
+ return config_path if config_path.exist?
25
+ current = current.join('..')
26
+ return nil if current.root?
27
+ end
28
+ end
29
+
19
30
  # Generate a rbs lockfile from Gemfile.lock to `config_path`.
20
31
  # If `with_lockfile` is true, it respects existing rbs lockfile.
21
32
  def self.generate_lockfile(config_path:, gemfile_lock_path:, with_lockfile: true)
@@ -69,6 +80,16 @@ module RBS
69
80
  @data['gems'] ||= []
70
81
  end
71
82
 
83
+ def gemfile_lock_path=(path)
84
+ @data['gemfile_lock_path'] = path.relative_path_from(@config_path.dirname).to_s
85
+ end
86
+
87
+ def gemfile_lock_path
88
+ path = @data['gemfile_lock_path']
89
+ return unless path
90
+ @config_path.dirname.join path
91
+ end
92
+
72
93
  # It raises an error when there are non-available libraries
73
94
  def check_rbs_availability!
74
95
  raise CollectionNotAvailable unless repo_path.exist?
@@ -211,6 +211,9 @@ module RBS
211
211
  end
212
212
 
213
213
  NoSuperclassFoundError.check!(super_name, env: env, location: primary.decl.location)
214
+ if super_class
215
+ InheritModuleError.check!(super_class, env: env)
216
+ end
214
217
 
215
218
  ancestors = OneAncestors.class_instance(
216
219
  type_name: type_name,
@@ -268,6 +271,9 @@ module RBS
268
271
  end
269
272
 
270
273
  NoSuperclassFoundError.check!(super_name, env: env, location: primary.decl.location)
274
+ if super_class
275
+ InheritModuleError.check!(super_class, env: env)
276
+ end
271
277
 
272
278
  ancestors = OneAncestors.singleton(
273
279
  type_name: type_name,