rbs 3.1.3 → 3.2.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
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