rbs 3.1.3 → 3.2.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.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +0 -6
  3. data/CHANGELOG.md +68 -0
  4. data/Gemfile +0 -6
  5. data/Gemfile.lock +12 -21
  6. data/README.md +1 -1
  7. data/Rakefile +44 -0
  8. data/Steepfile +3 -3
  9. data/core/array.rbs +0 -8
  10. data/core/builtin.rbs +28 -8
  11. data/core/constants.rbs +13 -5
  12. data/core/exception.rbs +1 -1
  13. data/core/global_variables.rbs +27 -27
  14. data/core/io.rbs +163 -172
  15. data/core/kernel.rbs +7 -4
  16. data/core/module.rbs +34 -32
  17. data/core/object.rbs +2 -2
  18. data/core/string_io.rbs +9 -0
  19. data/core/thread.rbs +25 -1
  20. data/core/time.rbs +3 -3
  21. data/docs/CONTRIBUTING.md +1 -1
  22. data/docs/rbs_by_example.md +16 -35
  23. data/docs/repo.md +1 -1
  24. data/docs/sigs.md +7 -7
  25. data/docs/stdlib.md +2 -3
  26. data/docs/syntax.md +40 -40
  27. data/lib/rbs/cli.rb +15 -4
  28. data/lib/rbs/collection/installer.rb +5 -2
  29. data/lib/rbs/collection/sources/stdlib.rb +5 -1
  30. data/lib/rbs/errors.rb +8 -1
  31. data/lib/rbs/file_finder.rb +1 -1
  32. data/lib/rbs/prototype/rb.rb +64 -6
  33. data/lib/rbs/prototype/rbi.rb +2 -6
  34. data/lib/rbs/prototype/runtime.rb +29 -8
  35. data/lib/rbs/subtractor.rb +17 -0
  36. data/lib/rbs/type_name.rb +4 -4
  37. data/lib/rbs/version.rb +1 -1
  38. data/rbs.gemspec +1 -1
  39. data/schema/decls.json +1 -1
  40. data/sig/errors.rbs +54 -0
  41. data/sig/parser.rbs +2 -2
  42. data/sig/prototype/rb.rbs +9 -1
  43. data/sig/subtractor.rbs +4 -0
  44. data/stdlib/logger/0/logger.rbs +1 -1
  45. data/stdlib/observable/0/observable.rbs +219 -0
  46. data/stdlib/uri/0/common.rbs +24 -0
  47. data/stdlib/zlib/0/buf_error.rbs +79 -0
  48. data/stdlib/zlib/0/data_error.rbs +79 -0
  49. data/stdlib/zlib/0/deflate.rbs +276 -0
  50. data/stdlib/zlib/0/error.rbs +89 -0
  51. data/stdlib/zlib/0/gzip_file/crc_error.rbs +115 -0
  52. data/stdlib/zlib/0/gzip_file/error.rbs +128 -0
  53. data/stdlib/zlib/0/gzip_file/length_error.rbs +115 -0
  54. data/stdlib/zlib/0/gzip_file/no_footer.rbs +114 -0
  55. data/stdlib/zlib/0/gzip_file.rbs +228 -0
  56. data/stdlib/zlib/0/gzip_reader.rbs +362 -0
  57. data/stdlib/zlib/0/gzip_writer.rbs +237 -0
  58. data/stdlib/zlib/0/inflate.rbs +249 -0
  59. data/stdlib/zlib/0/mem_error.rbs +79 -0
  60. data/stdlib/zlib/0/need_dict.rbs +82 -0
  61. data/stdlib/zlib/0/stream_end.rbs +80 -0
  62. data/stdlib/zlib/0/stream_error.rbs +80 -0
  63. data/stdlib/zlib/0/version_error.rbs +80 -0
  64. data/stdlib/zlib/0/zstream.rbs +270 -0
  65. metadata +24 -8
  66. data/stdlib/prime/0/integer-extension.rbs +0 -41
  67. data/stdlib/prime/0/manifest.yaml +0 -2
  68. data/stdlib/prime/0/prime.rbs +0 -372
data/docs/syntax.md CHANGED
@@ -51,7 +51,7 @@ _proc_ ::= _parameters?_ _self-type-binding?_ _block?_ `->` _type_
51
51
 
52
52
  Class instance type denotes _an instance of a class_.
53
53
 
54
- ```
54
+ ```rbs
55
55
  Integer # Instance of Integer class
56
56
  ::Integer # Instance of ::Integer class
57
57
  Hash[Symbol, String] # Instance of Hash class with type application of Symbol and String
@@ -61,7 +61,7 @@ Hash[Symbol, String] # Instance of Hash class with type application of S
61
61
 
62
62
  Interface type denotes _type of a value which can be a subtype of the interface_.
63
63
 
64
- ```
64
+ ```rbs
65
65
  _ToS # _ToS interface
66
66
  ::MyApp::_Each[String] # Interface name with namespace and type application
67
67
  ```
@@ -72,7 +72,7 @@ Alias type denotes an alias declared with _alias declaration_.
72
72
 
73
73
  The name of type aliases starts with lowercase `[a-z]`.
74
74
 
75
- ```
75
+ ```rbs
76
76
  name
77
77
  ::JSON::t # Alias name with namespace
78
78
  list[Integer] # Type alias can be generic
@@ -82,7 +82,7 @@ list[Integer] # Type alias can be generic
82
82
 
83
83
  Class singleton type denotes _the type of a singleton object of a class_.
84
84
 
85
- ```
85
+ ```rbs
86
86
  singleton(String)
87
87
  singleton(::Hash) # Class singleton type cannot be parametrized.
88
88
  ```
@@ -91,7 +91,7 @@ singleton(::Hash) # Class singleton type cannot be parametrized.
91
91
 
92
92
  Literal type denotes _a type with only one value of the literal_.
93
93
 
94
- ```
94
+ ```rbs
95
95
  123 # Integer
96
96
  "hello world" # A string
97
97
  :to_s # A symbol
@@ -102,7 +102,7 @@ true # true or false
102
102
 
103
103
  Union type denotes _a type of one of the given types_.
104
104
 
105
- ```
105
+ ```rbs
106
106
  Integer | String # Integer or String
107
107
  Array[Integer | String] # Array of Integer or String
108
108
  ```
@@ -111,7 +111,7 @@ Array[Integer | String] # Array of Integer or String
111
111
 
112
112
  Intersection type denotes _a type of all of the given types_.
113
113
 
114
- ```
114
+ ```rbs
115
115
  _Reader & _Writer # _Reader and _Writer
116
116
  ```
117
117
 
@@ -121,7 +121,7 @@ Note that `&` has higher precedence than `|` that `A & B | C` is `(A & B) | C`.
121
121
 
122
122
  Optional type denotes _a type of value or nil_.
123
123
 
124
- ```
124
+ ```rbs
125
125
  Integer?
126
126
  Array[Integer?]
127
127
  ```
@@ -130,7 +130,7 @@ Array[Integer?]
130
130
 
131
131
  Records are `Hash` objects, fixed set of keys, and heterogeneous.
132
132
 
133
- ```
133
+ ```rbs
134
134
  { id: Integer, name: String } # Hash object like `{ id: 31, name: String }`
135
135
  ```
136
136
 
@@ -138,7 +138,7 @@ Records are `Hash` objects, fixed set of keys, and heterogeneous.
138
138
 
139
139
  Tuples are `Array` objects, fixed size and heterogeneous.
140
140
 
141
- ```
141
+ ```rbs
142
142
  [ ] # Empty like `[]`
143
143
  [String] # Single string like `["hi"]`
144
144
  [Integer, Integer] # Pair of integers like `[1, 2]`
@@ -149,7 +149,7 @@ Tuples are `Array` objects, fixed size and heterogeneous.
149
149
 
150
150
  ### Type variable
151
151
 
152
- ```
152
+ ```rbs
153
153
  U
154
154
  T
155
155
  S
@@ -159,7 +159,7 @@ Elem
159
159
  Type variables cannot be distinguished from _class instance types_.
160
160
  They are scoped in _class/module/interface/alias declaration_ or _generic method types_.
161
161
 
162
- ```
162
+ ```rbs
163
163
  class Ref[T] # Object is scoped in the class declaration.
164
164
  @value: T # Type variable `T`
165
165
  def map: [X] { (T) -> X } -> Ref[X] # X is a type variable scoped in the method type.
@@ -193,7 +193,7 @@ It is an alias of `top` type, and you can use `boolish` if we want to allow any
193
193
 
194
194
  We can see an example at the definition of `Enumerable#find`:
195
195
 
196
- ```
196
+ ```rbs
197
197
  module Enumerable[Elem, Return]
198
198
  def find: () { (Elem) -> boolish } -> Elem?
199
199
  end
@@ -201,7 +201,7 @@ end
201
201
 
202
202
  We want to write something like:
203
203
 
204
- ```
204
+ ```ruby
205
205
  array.find {|x| x && x.some_test? } # The block will return (bool | nil)
206
206
  ```
207
207
 
@@ -218,7 +218,7 @@ They are all equivalent for the type system; they are all _top type_.
218
218
 
219
219
  Proc type denotes type of procedures, `Proc` instances.
220
220
 
221
- ```
221
+ ```rbs
222
222
  ^(Integer) -> String # A procedure with an `Integer` parameter and returns `String`
223
223
  ^(?String, size: Integer) -> bool # A procedure with `String` optional parameter, `size` keyword of `Integer`, and returns `bool`
224
224
  ```
@@ -266,7 +266,7 @@ Variable name can be used for documentation.
266
266
 
267
267
  #### Examples
268
268
 
269
- ```
269
+ ```rbs
270
270
  # Two required positional `Integer` parameters, and returns `String`
271
271
  (Integer, Integer) -> String
272
272
 
@@ -359,7 +359,7 @@ _method-name_ ::= ...
359
359
 
360
360
  An instance variable definition consists of the name of an instance variable and its type.
361
361
 
362
- ```
362
+ ```rbs
363
363
  @name: String
364
364
  @value: Hash[Symbol, Key]
365
365
  ```
@@ -370,7 +370,7 @@ Method definition has several syntax variations.
370
370
 
371
371
  You can write `self.` or `self?.` before the name of the method to specify the kind of method: instance, singleton, or module function.
372
372
 
373
- ```
373
+ ```rbs
374
374
  def to_s: () -> String # Defines a instance method
375
375
  def self.new: () -> AnObject # Defines singleton method
376
376
  def self?.sqrt: (Numeric) -> Numeric # self? is for `module_function`s
@@ -380,7 +380,7 @@ def self?.sqrt: (Numeric) -> Numeric # self? is for `module_function`s
380
380
 
381
381
  The method type can be connected with `|`s to define an overloaded method.
382
382
 
383
- ```
383
+ ```rbs
384
384
  def +: (Float) -> Float
385
385
  | (Integer) -> Integer
386
386
  | (Numeric) -> Numeric
@@ -388,7 +388,7 @@ def +: (Float) -> Float
388
388
 
389
389
  Overloaded method can have `...` to overload an existing method. It is useful for monkey-patching.
390
390
 
391
- ```
391
+ ```rbs
392
392
  def +: (Float) -> Float
393
393
  def +: (BigDecimal) -> BigDecimal
394
394
  | ...
@@ -396,14 +396,14 @@ def +: (BigDecimal) -> BigDecimal
396
396
 
397
397
  You need extra parentheses on return type to avoid ambiguity.
398
398
 
399
- ```
399
+ ```rbs
400
400
  def +: (Float | Integer) -> (Float | Integer)
401
401
  | (Numeric) -> Numeric
402
402
  ```
403
403
 
404
404
  Adding `public` and `private` modifier changes the visibility of the method.
405
405
 
406
- ```
406
+ ```rbs
407
407
  private def puts: (*untyped) -> void # Defines private instance method
408
408
 
409
409
  public def self.puts: (*untyped) -> void # Defines public singleton method
@@ -417,7 +417,7 @@ Attribute definitions help to define methods and instance variables based on the
417
417
 
418
418
  You can specify the name of instance variable using `(@some_name)` syntax and also omit the instance variable definition by specifying `()`.
419
419
 
420
- ```
420
+ ```rbs
421
421
  # Defines `id` method and `@id` instance variable.
422
422
  attr_reader id: Integer
423
423
  # @id: Integer
@@ -436,7 +436,7 @@ attr_accessor people (): Array[Person]
436
436
 
437
437
  Attribute definitions can have the `public` and `private` modifiers like method definitions:
438
438
 
439
- ```
439
+ ```rbs
440
440
  private attr_accessor id: Integer
441
441
 
442
442
  private attr_reader self.name: String
@@ -446,7 +446,7 @@ private attr_reader self.name: String
446
446
 
447
447
  You can define mixins between class and modules.
448
448
 
449
- ```
449
+ ```rbs
450
450
  include Kernel
451
451
  include Enumerable[String, void]
452
452
  extend ActiveSupport::Concern
@@ -454,7 +454,7 @@ extend ActiveSupport::Concern
454
454
 
455
455
  You can also `include` or `extend` an interface.
456
456
 
457
- ```
457
+ ```rbs
458
458
  include _Hashing
459
459
  extend _LikeString
460
460
  ```
@@ -465,7 +465,7 @@ This allows importing `def`s from the interface to help developer implementing a
465
465
 
466
466
  You can define an alias between methods.
467
467
 
468
- ```
468
+ ```rbs
469
469
  def map: [X] () { (String) -> X } -> Array[X]
470
470
  alias collect map # `#collect` has the same type with `map`
471
471
  ```
@@ -548,7 +548,7 @@ Class declaration can have type parameters and superclass. When you omit supercl
548
548
 
549
549
  Module declaration takes optional _self type_ parameter, which defines a constraint about a class when the module is mixed.
550
550
 
551
- ```
551
+ ```rbs
552
552
  interface _Each[A, B]
553
553
  def each: { (A) -> void } -> B
554
554
  end
@@ -572,7 +572,7 @@ class Bar = Array
572
572
 
573
573
  The syntax defines a class and the definition is equivalent to the right-hand-side.
574
574
 
575
- ```
575
+ ```rbs
576
576
  class Baz < Bar[String] # Class alias can be inherited
577
577
  include Foo # Module alias can be included
578
578
  end
@@ -590,7 +590,7 @@ end
590
590
 
591
591
  Interface declaration can have parameters but allows only a few of the members.
592
592
 
593
- ```
593
+ ```rbs
594
594
  interface _Hashing
595
595
  def hash: () -> Integer
596
596
  def eql?: (untyped) -> bool
@@ -602,7 +602,7 @@ There are several limitations which are not described in the grammar.
602
602
  1. Interface cannot `include` modules
603
603
  2. Interface cannot have singleton method definitions
604
604
 
605
- ```
605
+ ```rbs
606
606
  interface _Foo
607
607
  include Bar # Error: cannot include modules
608
608
  def self.new: () -> Foo # Error: cannot include singleton method definitions
@@ -613,14 +613,14 @@ end
613
613
 
614
614
  You can declare an alias of types.
615
615
 
616
- ```
616
+ ```rbs
617
617
  type subject = Attendee | Speaker
618
618
  type JSON::t = Integer | TrueClass | FalseClass | String | Hash[Symbol, t] | Array[t]
619
619
  ```
620
620
 
621
621
  Type alias can be generic like class, module, and interface.
622
622
 
623
- ```
623
+ ```rbs
624
624
  type list[out T] = [T, list[T]] | nil
625
625
  ```
626
626
 
@@ -628,7 +628,7 @@ type list[out T] = [T, list[T]] | nil
628
628
 
629
629
  You can declare a constant.
630
630
 
631
- ```
631
+ ```rbs
632
632
  Person::DefaultEmailAddress: String
633
633
  ```
634
634
 
@@ -636,13 +636,13 @@ Person::DefaultEmailAddress: String
636
636
 
637
637
  You can declare a global variable.
638
638
 
639
- ```
639
+ ```rbs
640
640
  $LOAD_PATH: Array[String]
641
641
  ```
642
642
 
643
643
  ### Generics
644
644
 
645
- ```md
645
+ ```markdown
646
646
  _module-type-parameter_ ::= _generics-unchecked_ _generics-variance_ _type-variable_ _generics-bound_
647
647
 
648
648
  _method-type-param_ ::= _type-variable_ _generics-bound_
@@ -677,7 +677,7 @@ For classes with type parameters, you may specify if they are "invariant" (defau
677
677
 
678
678
  For example, an `Array` of `String` can almost be considered to be an `Array` of `Object`, but not the reverse, so we can think of:
679
679
 
680
- ```
680
+ ```rbs
681
681
  # The `T` type parameter is covariant.
682
682
  class Array[out T]
683
683
  # etc.
@@ -732,7 +732,7 @@ The upper bound must be one of a class instance type, interface type, or class s
732
732
 
733
733
  Directives are placed at the top of a file and provides per-file-basis features.
734
734
 
735
- ```
735
+ ```markdown
736
736
  _use-directive_ ::= `use` _use-clauses_
737
737
 
738
738
  _use-clauses_ ::= _use-clause_ `,` ... `,` _use-clause_
@@ -745,7 +745,7 @@ _use-clause_ ::= _type-name_ # Single use clause
745
745
  The *use directive* defines relative type names that is an alias of other type names.
746
746
  We can use the simple type names if it is declared with *use*.
747
747
 
748
- ```
748
+ ```rbs
749
749
  use RBS::Namespace # => Defines `Namespace`
750
750
  use RBS::TypeName as TN # => Defines `TN`
751
751
  use RBS::AST::* # => Defines modules under `::RBS::AST::` namespace
@@ -755,7 +755,7 @@ use RBS::AST::* # => Defines modules under `::RBS::AST::` namespace
755
755
 
756
756
  You can write single line comments. Comments must be on their own line. Comments can lead with whitespace.
757
757
 
758
- ```
758
+ ```rbs
759
759
  # This if interface Foo
760
760
  # Usage of Foo is bar
761
761
  interface _Foo
data/lib/rbs/cli.rb CHANGED
@@ -645,6 +645,7 @@ EOU
645
645
  relative_libs = []
646
646
  merge = false
647
647
  owners_included = []
648
+ outline = false
648
649
 
649
650
  OptionParser.new do |opts|
650
651
  opts.banner = <<EOU
@@ -657,7 +658,7 @@ Examples:
657
658
 
658
659
  $ rbs prototype runtime String
659
660
  $ rbs prototype runtime --require set Set
660
- $ rbs prototype runtime -R lib/rbs RBS::*
661
+ $ rbs prototype runtime -R lib/rbs RBS RBS::*
661
662
 
662
663
  Options:
663
664
  EOU
@@ -673,6 +674,9 @@ EOU
673
674
  opts.on("--method-owner CLASS", "Generate method prototypes if the owner of the method is [CLASS]") do |klass|
674
675
  owners_included << klass
675
676
  end
677
+ opts.on("--outline", "Generates only module/class/constant declaration (no method definition)") do
678
+ outline = true
679
+ end
676
680
  end.parse!(args)
677
681
 
678
682
  loader = options.loader()
@@ -686,7 +690,10 @@ EOU
686
690
  eval("require_relative(lib)", binding, "rbs")
687
691
  end
688
692
 
689
- decls = Prototype::Runtime.new(patterns: args, env: env, merge: merge, owners_included: owners_included).decls
693
+ runtime = Prototype::Runtime.new(patterns: args, env: env, merge: merge, owners_included: owners_included)
694
+ runtime.outline = outline
695
+
696
+ decls = runtime.decls
690
697
 
691
698
  writer = Writer.new(out: stdout)
692
699
  writer.write decls
@@ -961,7 +968,7 @@ Options:
961
968
  Parser.public_send(parse_method, buf, require_eof: true)
962
969
  end
963
970
  rescue RBS::ParsingError => ex
964
- stdout.puts ex.message
971
+ stdout.print ex.detailed_message(highlight: true)
965
972
  syntax_error = true
966
973
  end
967
974
 
@@ -1241,7 +1248,11 @@ EOB
1241
1248
  w.write(subtracted)
1242
1249
 
1243
1250
  if write_to_file
1244
- rbs_path.write(io.string)
1251
+ if io.string.empty?
1252
+ rbs_path.delete
1253
+ else
1254
+ rbs_path.write(io.string)
1255
+ end
1245
1256
  else
1246
1257
  stdout.puts(io.string)
1247
1258
  end
@@ -14,7 +14,10 @@ module RBS
14
14
  def install_from_lockfile
15
15
  install_to = lockfile.fullpath
16
16
  install_to.mkpath
17
- lockfile.gems.each_value do |gem|
17
+ selected = lockfile.gems.select do |name, gem|
18
+ gem[:source].has?(name, gem[:version])
19
+ end
20
+ selected.each_value do |gem|
18
21
  gem[:source].install(
19
22
  dest: install_to,
20
23
  name: gem[:name],
@@ -22,7 +25,7 @@ module RBS
22
25
  stdout: stdout
23
26
  )
24
27
  end
25
- stdout.puts "It's done! #{lockfile.gems.size} gems' RBSs now installed."
28
+ stdout.puts "It's done! #{selected.size} gems' RBSs now installed."
26
29
  end
27
30
  end
28
31
  end
@@ -27,7 +27,11 @@ module RBS
27
27
  end
28
28
 
29
29
  def manifest_of(name, version)
30
- manifest_path = (lookup(name, version) or raise).join('manifest.yaml')
30
+ unless path = lookup(name, version)
31
+ RBS.logger.warn "`#{name}` is specified in rbs_collection.lock.yaml. But it is not found in #{REPO.dirs.join(",")}"
32
+ return
33
+ end
34
+ manifest_path = path.join('manifest.yaml')
31
35
  YAML.safe_load(manifest_path.read) if manifest_path.exist?
32
36
  end
33
37
 
data/lib/rbs/errors.rb CHANGED
@@ -22,7 +22,14 @@ module RBS
22
22
 
23
23
  module DetailedMessageable
24
24
  def detailed_message(highlight: false, **)
25
- msg = super
25
+ msg = if Exception.method_defined?(:detailed_message)
26
+ super
27
+ else
28
+ # Failback to `#message` in Ruby 3.1 or earlier
29
+ "#{message} (#{self.class.name})"
30
+ end
31
+
32
+ return msg unless location
26
33
 
27
34
  # Support only one line
28
35
  return msg unless location.start_line == location.end_line
@@ -5,7 +5,7 @@ module RBS
5
5
  module_function
6
6
 
7
7
  def self.each_file(path, immediate:, skip_hidden:, &block)
8
- return enum_for(__method__, path, immediate: immediate, skip_hidden: skip_hidden) unless block
8
+ return enum_for((__method__ or raise), path, immediate: immediate, skip_hidden: skip_hidden) unless block
9
9
 
10
10
  case
11
11
  when path.file?
@@ -5,11 +5,11 @@ module RBS
5
5
  class RB
6
6
  include Helpers
7
7
 
8
- Context = _ = Struct.new(:module_function, :singleton, :namespace, keyword_init: true) do
8
+ Context = _ = Struct.new(:module_function, :singleton, :namespace, :in_def, keyword_init: true) do
9
9
  # @implements Context
10
10
 
11
11
  def self.initial(namespace: Namespace.root)
12
- self.new(module_function: false, singleton: false, namespace: namespace)
12
+ self.new(module_function: false, singleton: false, namespace: namespace, in_def: false)
13
13
  end
14
14
 
15
15
  def method_kind
@@ -29,6 +29,14 @@ module RBS
29
29
  :instance
30
30
  end
31
31
  end
32
+
33
+ def enter_namespace(namespace)
34
+ Context.initial(namespace: self.namespace + namespace)
35
+ end
36
+
37
+ def update(module_function: self.module_function, singleton: self.singleton, in_def: self.in_def)
38
+ Context.new(module_function: module_function, singleton: singleton, namespace: namespace, in_def: in_def)
39
+ end
32
40
  end
33
41
 
34
42
  attr_reader :source_decls
@@ -121,11 +129,12 @@ module RBS
121
129
 
122
130
  decls.push kls
123
131
 
124
- new_ctx = Context.initial(namespace: context.namespace + kls.name.to_namespace)
132
+ new_ctx = context.enter_namespace(kls.name.to_namespace)
125
133
  each_node class_body do |child|
126
134
  process child, decls: kls.members, comments: comments, context: new_ctx
127
135
  end
128
136
  remove_unnecessary_accessibility_methods! kls.members
137
+ sort_members! kls.members
129
138
 
130
139
  when :MODULE
131
140
  module_name, *module_body = node.children
@@ -142,11 +151,12 @@ module RBS
142
151
 
143
152
  decls.push mod
144
153
 
145
- new_ctx = Context.initial(namespace: context.namespace + mod.name.to_namespace)
154
+ new_ctx = context.enter_namespace(mod.name.to_namespace)
146
155
  each_node module_body do |child|
147
156
  process child, decls: mod.members, comments: comments, context: new_ctx
148
157
  end
149
158
  remove_unnecessary_accessibility_methods! mod.members
159
+ sort_members! mod.members
150
160
 
151
161
  when :SCLASS
152
162
  this, body = node.children
@@ -195,6 +205,11 @@ module RBS
195
205
 
196
206
  decls.push member unless decls.include?(member)
197
207
 
208
+ new_ctx = context.update(singleton: kind == :singleton, in_def: true)
209
+ each_node def_body.children do |child|
210
+ process child, decls: decls, comments: comments, context: new_ctx
211
+ end
212
+
198
213
  when :ALIAS
199
214
  new_name, old_name = node.children.map { |c| literal_to_symbol(c) }
200
215
  member = AST::Members::Alias.new(
@@ -306,7 +321,7 @@ module RBS
306
321
  if args.empty?
307
322
  context.module_function = true
308
323
  else
309
- module_func_context = context.dup.tap { |ctx| ctx.module_function = true }
324
+ module_func_context = context.update(module_function: true)
310
325
  args.each do |arg|
311
326
  if arg && (name = literal_to_symbol(arg))
312
327
  if (i, defn = find_def_index_by_name(decls, name))
@@ -377,6 +392,39 @@ module RBS
377
392
  comment: comments[node.first_lineno - 1]
378
393
  )
379
394
 
395
+ when :IASGN
396
+ case [context.singleton, context.in_def]
397
+ when [true, true], [false, false]
398
+ member = AST::Members::ClassInstanceVariable.new(
399
+ name: node.children.first,
400
+ type: Types::Bases::Any.new(location: nil),
401
+ location: nil,
402
+ comment: comments[node.first_lineno - 1]
403
+ )
404
+ when [false, true]
405
+ member = AST::Members::InstanceVariable.new(
406
+ name: node.children.first,
407
+ type: Types::Bases::Any.new(location: nil),
408
+ location: nil,
409
+ comment: comments[node.first_lineno - 1]
410
+ )
411
+ when [true, false]
412
+ # The variable is for the singleton class of the class object.
413
+ # RBS does not have a way to represent it. So we ignore it.
414
+ else
415
+ raise 'unreachable'
416
+ end
417
+
418
+ decls.push member if member && !decls.include?(member)
419
+
420
+ when :CVASGN
421
+ member = AST::Members::ClassVariable.new(
422
+ name: node.children.first,
423
+ type: Types::Bases::Any.new(location: nil),
424
+ location: nil,
425
+ comment: comments[node.first_lineno - 1]
426
+ )
427
+ decls.push member unless decls.include?(member)
380
428
  else
381
429
  process_children(node, decls: decls, comments: comments, context: context)
382
430
  end
@@ -413,7 +461,7 @@ module RBS
413
461
  when :SELF
414
462
  context.namespace.to_type_name
415
463
  when :CONST, :COLON2, :COLON3
416
- const_to_name!(node)
464
+ const_to_name!(node) rescue nil
417
465
  end
418
466
  end
419
467
  end
@@ -743,6 +791,16 @@ module RBS
743
791
  ]
744
792
  end
745
793
  end
794
+
795
+ def sort_members!(decls)
796
+ i = 0
797
+ orders = {
798
+ AST::Members::ClassVariable => -3,
799
+ AST::Members::ClassInstanceVariable => -2,
800
+ AST::Members::InstanceVariable => -1,
801
+ }
802
+ decls.sort_by! { |decl| [orders.fetch(decl.class, 0), i += 1] }
803
+ end
746
804
  end
747
805
  end
748
806
  end
@@ -479,7 +479,7 @@ module RBS
479
479
  else
480
480
  Types::ClassInstance.new(name: const_to_name(type_node), args: [], location: nil)
481
481
  end
482
- when type_node.type == :COLON2
482
+ when type_node.type == :COLON2 || type_node.type == :COLON3
483
483
  Types::ClassInstance.new(name: const_to_name(type_node), args: [], location: nil)
484
484
  when call_node?(type_node, name: :[], receiver: -> (_) { true })
485
485
  # The type_node represents a type application
@@ -553,11 +553,7 @@ module RBS
553
553
  TypeName.new(name: node.children[0], namespace: Namespace.empty)
554
554
  when :COLON2
555
555
  if node.children[0]
556
- if node.children[0].type == :COLON3
557
- namespace = Namespace.root
558
- else
559
- namespace = const_to_name(node.children[0]).to_namespace
560
- end
556
+ namespace = const_to_name(node.children[0]).to_namespace
561
557
  else
562
558
  namespace = Namespace.empty
563
559
  end