rbs 0.4.0 → 0.5.0

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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +7 -1
  3. data/.gitignore +1 -1
  4. data/CHANGELOG.md +7 -0
  5. data/Gemfile +12 -0
  6. data/README.md +86 -47
  7. data/Rakefile +54 -21
  8. data/bin/rbs-prof +9 -0
  9. data/bin/run_in_md.rb +49 -0
  10. data/lib/rbs.rb +2 -0
  11. data/lib/rbs/ast/declarations.rb +62 -7
  12. data/lib/rbs/ast/members.rb +41 -17
  13. data/lib/rbs/cli.rb +299 -121
  14. data/lib/rbs/constant.rb +4 -4
  15. data/lib/rbs/constant_table.rb +50 -44
  16. data/lib/rbs/definition.rb +175 -59
  17. data/lib/rbs/definition_builder.rb +647 -603
  18. data/lib/rbs/environment.rb +338 -209
  19. data/lib/rbs/environment_walker.rb +14 -23
  20. data/lib/rbs/errors.rb +141 -3
  21. data/lib/rbs/parser.y +14 -9
  22. data/lib/rbs/prototype/rb.rb +100 -112
  23. data/lib/rbs/prototype/rbi.rb +4 -2
  24. data/lib/rbs/prototype/runtime.rb +10 -6
  25. data/lib/rbs/substitution.rb +8 -1
  26. data/lib/rbs/test/hook.rb +2 -2
  27. data/lib/rbs/test/setup.rb +3 -1
  28. data/lib/rbs/test/test_helper.rb +2 -5
  29. data/lib/rbs/test/type_check.rb +1 -2
  30. data/lib/rbs/type_name_resolver.rb +58 -0
  31. data/lib/rbs/types.rb +94 -2
  32. data/lib/rbs/validator.rb +51 -0
  33. data/lib/rbs/variance_calculator.rb +12 -2
  34. data/lib/rbs/version.rb +1 -1
  35. data/lib/rbs/writer.rb +125 -89
  36. data/rbs.gemspec +0 -10
  37. data/schema/decls.json +15 -0
  38. data/schema/members.json +3 -0
  39. data/stdlib/benchmark/benchmark.rbs +151 -151
  40. data/stdlib/builtin/enumerable.rbs +1 -1
  41. data/stdlib/builtin/file.rbs +0 -3
  42. data/stdlib/builtin/io.rbs +4 -4
  43. data/stdlib/builtin/thread.rbs +2 -2
  44. data/stdlib/csv/csv.rbs +4 -6
  45. data/stdlib/fiber/fiber.rbs +1 -1
  46. data/stdlib/json/json.rbs +1 -1
  47. data/stdlib/mutex_m/mutex_m.rbs +77 -0
  48. data/stdlib/pathname/pathname.rbs +6 -6
  49. data/stdlib/prime/integer-extension.rbs +1 -1
  50. data/stdlib/prime/prime.rbs +44 -44
  51. data/stdlib/tmpdir/tmpdir.rbs +1 -1
  52. metadata +8 -129
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 77a83be097e5de26f4541a25fb744a31574d0f0b94d94848e11cae49d095693a
4
- data.tar.gz: 4619e6ae9f31e32ac6d2da902b11980644df037b9d254b5919fe2eff1f43bdc7
3
+ metadata.gz: a5318ae7911a3e7e4e1bed761e0c7b8d1fc248e698b0d53f8a39d388da5617f0
4
+ data.tar.gz: d90f20d41372bcc852f49b844aa6b6b5367d9d88ec686a13ab00841f1cf1e2ed
5
5
  SHA512:
6
- metadata.gz: '095abed7b0453d72a545760d8a165bb2a3415e3f741b004926b600b8e1e1260dc752e91d86d33e0c770d3011885bea1fa728708707687c59d3a1ad9707b672c7'
7
- data.tar.gz: 94b3f4fc317d701c327b7519068ec590409ceff1208660c44f83440c9d3ed419c83ca29adf7137c10a1fb7c3d7ed7b0808e0a8a5fc5dedd66ca900981674ae90
6
+ metadata.gz: 702ae082267eb6a087e19c5a37a83aaaeea0f76e83eba7cc984a15cca869745d1b934231bf6910dbbba972a06301948eca740aa2a8fc49c378487a030befe909
7
+ data.tar.gz: 8f467c52d50c25886965e1762f7c52f246cb90fa313c7d0a9400051f32c7f3603ada0142cf90ebfad4b56ccbaf57bacd5d1467cb8daf20247254c90937b9c599
@@ -24,5 +24,11 @@ jobs:
24
24
  ruby -v
25
25
  gem install bundler
26
26
  bin/setup
27
- bundle exec rake
27
+ bundle exec rake test
28
+ bundle exec rake stdlib_test
29
+ bundle exec rake rubocop
30
+ bundle exec rake validate
31
+ bundle exec rake test_doc
28
32
  bundle exec rake build
33
+ RBS_GENERATE_TEST_PATH=/tmp/Array_test.rb bundle exec rake 'generate:stdlib_test[Array]'
34
+ ruby -c /tmp/Array_test.rb
data/.gitignore CHANGED
@@ -5,8 +5,8 @@
5
5
  /pkg/
6
6
  /spec/reports/
7
7
  /tmp/
8
- /Gemfile.lock
9
8
  /.ruby-version
10
9
  /lib/rbs/parser.rb
11
10
  /lib/rbs/parser.output
12
11
  /vendor/sigs
12
+ /Gemfile.lock
@@ -2,6 +2,13 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.5.0 (2020-07-04)
6
+
7
+ * Signature updates for `Mutex_m`, `IO`, and `Enumerable`.
8
+ * Syntax update. [#307](https://github.com/ruby/rbs/pull/307)
9
+ * AST command prints _absolute_ type names with file name filtering. [#312](https://github.com/ruby/rbs/pull/312)
10
+ * Improve CLI message. [#309](https://github.com/ruby/rbs/pull/309)
11
+
5
12
  ## 0.4.0 (2020-06-15)
6
13
 
7
14
  * Signature update for `Fiber`, `Encoding`, and `Enumerator`.
data/Gemfile CHANGED
@@ -3,4 +3,16 @@ source "https://rubygems.org"
3
3
  # Specify your gem's dependencies in rbs.gemspec
4
4
  gemspec
5
5
 
6
+ # Development dependencies
7
+ gem "rake"
8
+ gem "minitest"
9
+ gem "racc"
10
+ gem "rubocop"
11
+ gem "rubocop-rubycw"
12
+ gem "minitest-reporters"
13
+ gem "json"
14
+ gem "json-schema"
15
+ gem 'stackprof'
16
+
17
+ # Test gems
6
18
  gem "rbs-amber", path: "test/assets/test-gem"
data/README.md CHANGED
@@ -1,79 +1,118 @@
1
1
  # RBS
2
2
 
3
- RBS provides syntax and semantics definition for the `Ruby Signature` language, `.rbs` files.
4
- It consists of a parser, the syntax, and class definition interpreter, the semantics.
3
+ RBS is a language to describe the structure of Ruby programs.
4
+ You can write down the definition of a class or module: methods defined in the class, instance variables and their types, and inheritance/mix-in relations.
5
+ It also allows declaring constants and global variables.
5
6
 
6
- ## Build
7
+ The following is a small example of RBS for a chat app.
7
8
 
8
- We haven't published a gem yet.
9
- You need to install the dependencies, and build its parser with `bin/setup`.
9
+ <!-- run-start:a.rbs:bundle exec rbs -I a.rbs validate -->
10
+ ```rbs
11
+ module ChatApp
12
+ VERSION: String
10
13
 
11
- ```
12
- $ bin/setup
13
- $ bundle exec exe/rbs
14
- ```
14
+ class User
15
+ attr_reader login: String
16
+ attr_reader email: String
15
17
 
16
- ## Usage
18
+ def initialize: (login: String, email: String) -> void
19
+ end
17
20
 
18
- ```
19
- $ rbs list
20
- $ rbs ancestors ::Object
21
- $ rbs methods ::Object
22
- $ rbs method ::Object tap
23
- ```
21
+ class Bot
22
+ attr_reader name: String
23
+ attr_reader email: String
24
+ attr_reader owner: User
24
25
 
25
- ### rbs list [--class|--module|--interface]
26
+ def initialize: (name: String, owner: User) -> void
27
+ end
26
28
 
27
- ```
28
- $ rbs list
29
- ```
29
+ class Message
30
+ attr_reader id: String
31
+ attr_reader string: String
32
+ attr_reader from: User | Bot # `|` means union types: `#from` can be `User` or `Bot`
33
+ attr_reader reply_to: Message? # `?` means optional type: `#reply_to` can be `nil`
30
34
 
31
- This command lists all of the classes/modules/interfaces defined in `.rbs` files.
35
+ def initialize: (from: User | Bot, string: String) -> void
32
36
 
33
- ### rbs ancestors [--singleton|--instance] CLASS
37
+ def reply: (from: User | Bot, string: String) -> Message
38
+ end
34
39
 
40
+ class Channel
41
+ attr_reader name: String
42
+ attr_reader messages: Array[Message]
43
+ attr_reader users: Array[User]
44
+ attr_reader bots: Array[Bot]
45
+
46
+ def initialize: (name: String) -> void
47
+
48
+ def each_member: () { (User | Bot) -> void } -> void # `{` and `}` means block.
49
+ | () -> Enumerable[User | Bot, void] # Method can be overloaded.
50
+ end
51
+ end
35
52
  ```
36
- $ rbs ancestors Array # ([].class.ancestors)
37
- $ rbs ancestors --singleton Array # (Array.class.ancestors)
38
- ```
53
+ <!-- run-end -->
39
54
 
40
- This command prints the _ancestors_ of the class.
41
- The name of the command is borrowed from `Class#ancestors`, but the semantics is a bit different.
42
- The `ancestors` command is more precise (I believe).
55
+ ## Installation
43
56
 
44
- ### rbs methods [--singleton|--instance] CLASS
57
+ Install the `rbs` gem. `$ gem install rbs` from the command line, or add a line in your `Gemfile`.
45
58
 
46
- ```
47
- $ rbs methods ::Integer # 1.methods
48
- $ rbs methods --singleton ::Object # Object.methods
59
+ ```rb
60
+ gem "rbs"
49
61
  ```
50
62
 
51
- This command prints all methods provided for the class.
63
+ ## CLI
52
64
 
53
- ### rbs method [--singleton|--instance] CLASS METHOD
65
+ The gem ships with the `rbs` command line tool to demonstrate what it can do and help develop RBS.
54
66
 
55
- ```
56
- $ rbs method ::Integer '+' # 1+2
57
- $ rbs method --singleton ::Object tap # Object.tap { ... }
67
+ ```bash
68
+ $ rbs version
69
+ $ rbs list
70
+ $ rbs ancestors ::Object
71
+ $ rbs methods ::Object
72
+ $ rbs method Object then
58
73
  ```
59
74
 
60
- This command prints type and properties of the method.
75
+ ## Library
61
76
 
62
- ### Options
77
+ There are two important concepts, _environment_ and _definition_.
63
78
 
64
- It accepts two global options, `-r` and `-I`.
79
+ An _environment_ is a dictionary that keeps track of all declarations. What is the declaration associated with `String` class? An _environment_ will give you the answer.
65
80
 
66
- `-r` is for libraries. You can specify the names of libraries.
81
+ A _definition_ gives you the detail of the class. What is the type of the return value of `gsub` method of the `String` class? The _definition_ for `String` class knows the list of methods it provides and their types.
67
82
 
68
- ```
69
- $ rbs -r set list
70
- ```
83
+ The following is a small code to retrieve the definition of the `String#gsub` method.
71
84
 
72
- `-I` is for application signatures. You can specify the name of directory.
85
+ <!-- run-start:a.rb:bundle exec ruby a.rb -->
86
+ ```rb
87
+ require "rbs"
73
88
 
89
+ loader = RBS::EnvironmentLoader.new()
90
+
91
+ # loader.add(path: Pathname("sig")) # Load .rbs files from `sig` directory
92
+ # loader.add(library: "pathname") # Load pathname library
93
+
94
+ environment = RBS::Environment.from_loader(loader).resolve_type_names
95
+
96
+ # ::String
97
+ string = RBS::TypeName.new(name: :String, namespace: RBS::Namespace.root)
98
+
99
+ # Class declaration for ::String
100
+ decl = environment.class_decls[string]
101
+
102
+ # Builder provides the translation from `declaration` to `definition`
103
+ builder = RBS::DefinitionBuilder.new(env: environment)
104
+
105
+ # Definition of instance of String
106
+ instance = builder.build_instance(string)
107
+ # Print the types of `gsub` method
108
+ puts instance.methods[:gsub].method_types.join("\n")
109
+
110
+ # Definition of singleton of String
111
+ singleton = builder.build_singleton(string)
112
+ # No `gsub` method for String singleton
113
+ puts singleton.methods[:gsub]
74
114
  ```
75
- $ rbs -I sig list
76
- ```
115
+ <!-- run-end -->
77
116
 
78
117
  ## Guides
79
118
 
data/Rakefile CHANGED
@@ -9,10 +9,23 @@ Rake::TestTask.new(:test) do |t|
9
9
  end
10
10
  end
11
11
 
12
- multitask :default => [:test, :stdlib_test, :rubocop, :validate]
12
+ multitask :default => [:test, :stdlib_test, :rubocop, :validate, :test_doc]
13
+
14
+ task :test_doc => :parser do
15
+ files = Dir.chdir(File.expand_path('..', __FILE__)) do
16
+ `git ls-files -z`.split("\x0").select do |file| Pathname(file).extname == ".md" end
17
+ end
18
+
19
+ sh "ruby bin/run_in_md.rb #{files.join(" ")}"
20
+ end
13
21
 
14
22
  task :validate => :parser do
15
23
  sh "rbs validate"
24
+
25
+ FileList["stdlib/*"].each do |path|
26
+ next if path =~ %r{stdlib/builtin}
27
+ sh "rbs -r#{File.basename(path)} validate"
28
+ end
16
29
  end
17
30
 
18
31
  FileList["test/stdlib/**/*_test.rb"].each do |test|
@@ -41,7 +54,7 @@ namespace :generate do
41
54
  raise "Class name is necessary. e.g. rake 'generate:stdlib_test[String]'"
42
55
  end
43
56
 
44
- path = Pathname("test/stdlib/#{klass}_test.rb")
57
+ path = Pathname(ENV["RBS_GENERATE_TEST_PATH"] || "test/stdlib/#{klass}_test.rb")
45
58
  raise "#{path} already exists!" if path.exist?
46
59
 
47
60
  require "erb"
@@ -53,35 +66,55 @@ namespace :generate do
53
66
  def initialize(klass)
54
67
  @klass = klass
55
68
 
56
- @env = Ruby::Signature::Environment.new
57
- Ruby::Signature::EnvironmentLoader.new.load(env: @env)
69
+ loader = RBS::EnvironmentLoader.new
70
+ Dir['stdlib/*'].each do |lib|
71
+ next if lib.end_with?('builtin')
72
+
73
+ loader.add(library: File.basename(lib))
74
+ end
75
+ @env = RBS::Environment.from_loader(loader).resolve_type_names
58
76
  end
59
77
 
60
78
  def call
61
79
  ERB.new(<<~ERB, trim_mode: "-").result(binding)
62
80
  require_relative "test_helper"
81
+ require 'rbs/test/test_helper'
82
+
83
+ <%- unless class_methods.empty? -%>
84
+ class <%= klass %>SingletonTest < Minitest::Test
85
+ include RBS::Test::TypeAssertions
63
86
 
64
- class <%= klass %>Test < StdlibTest
65
- target <%= klass %>
66
87
  # library "pathname", "set", "securerandom" # Declare library signatures to load
67
- using hook.refinement
88
+ testing "singleton(::<%= klass %>)"
89
+
68
90
  <%- class_methods.each do |method_name, definition| %>
69
- def test_class_method_<%= test_name_for(method_name) %>
70
- <%- definition.method_types.each do |method_type| -%>
71
- # <%= method_type %>
72
- <%= klass %>.<%= method_name %>
73
- <%- end -%>
91
+ def test_<%= test_name_for(method_name) %>
92
+ <%- definition.method_types.each do |method_type| -%>
93
+ assert_send_type "<%= method_type %>",
94
+ <%= klass %>, :<%= method_name %>
95
+ <%- end -%>
74
96
  end
75
97
  <%- end -%>
98
+ end
99
+ <%- end -%>
100
+
101
+ <%- unless instance_methods.empty? -%>
102
+ class <%= klass %>Test < Minitest::Test
103
+ include RBS::Test::TypeAssertions
104
+
105
+ # library "pathname", "set", "securerandom" # Declare library signatures to load
106
+ testing "::<%= klass %>"
107
+
76
108
  <%- instance_methods.each do |method_name, definition| %>
77
109
  def test_<%= test_name_for(method_name) %>
78
- <%- definition.method_types.each do |method_type| -%>
79
- # <%= method_type %>
80
- <%= klass %>.new.<%= method_name %>
81
- <%- end -%>
110
+ <%- definition.method_types.each do |method_type| -%>
111
+ assert_send_type "<%= method_type %>",
112
+ <%= klass %>.new, :<%= method_name %>
113
+ <%- end -%>
82
114
  end
83
115
  <%- end -%>
84
116
  end
117
+ <%- end -%>
85
118
  ERB
86
119
  end
87
120
 
@@ -117,18 +150,18 @@ namespace :generate do
117
150
  end
118
151
 
119
152
  def type_name
120
- @type_name ||= Ruby::Signature::TypeName.new(name: klass.to_sym, namespace: Ruby::Signature::Namespace.new(path: [], absolute: true))
153
+ @type_name ||= RBS::TypeName.new(name: klass.to_sym, namespace: RBS::Namespace.new(path: [], absolute: true))
121
154
  end
122
155
 
123
156
  def class_methods
124
- @class_methods ||= Ruby::Signature::DefinitionBuilder.new(env: env).build_singleton(type_name).methods.select {|_, definition|
125
- definition.implemented_in.name.absolute! == type_name
157
+ @class_methods ||= RBS::DefinitionBuilder.new(env: env).build_singleton(type_name).methods.select {|_, definition|
158
+ definition.implemented_in == type_name
126
159
  }
127
160
  end
128
161
 
129
162
  def instance_methods
130
- @instance_methods ||= Ruby::Signature::DefinitionBuilder.new(env: env).build_instance(type_name).methods.select {|_, definition|
131
- definition.implemented_in.name.absolute! == type_name
163
+ @instance_methods ||= RBS::DefinitionBuilder.new(env: env).build_instance(type_name).methods.select {|_, definition|
164
+ definition.implemented_in == type_name
132
165
  }
133
166
  end
134
167
  end
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "stackprof"
4
+
5
+ out = ENV["RBS_STACKPROF_OUT"] || 'tmp/stackprof-cpu-rbs.dump'
6
+
7
+ StackProf.run(mode: :cpu, out: out) do
8
+ load File.join(__dir__, "../exe/rbs")
9
+ end
@@ -0,0 +1,49 @@
1
+ require "tmpdir"
2
+ require "shellwords"
3
+
4
+ ARGV.each do |path|
5
+ puts "~~~~~~~ Checking #{path} ~~~~~~"
6
+ content = File.read(path)
7
+
8
+ snippets = []
9
+ lines = []
10
+ content.lines.each.with_index do |line, index|
11
+ case line
12
+ when /run-start:/
13
+ lines = [[line, index+1]]
14
+ when /run-end/
15
+ lines << [line, index+1]
16
+ snippets << lines
17
+ lines = []
18
+ else
19
+ lines << [line, index+1]
20
+ end
21
+ end
22
+
23
+ snippets.each do |lines|
24
+ puts ">>> Code detected: "
25
+ hd, _, *code_lines, _, _ = lines
26
+
27
+ head = hd[0]
28
+ head.gsub!(/^<!-- +/, "").gsub!(/ +-->$/, "")
29
+ _,name,command = head.split(/:/)
30
+
31
+ puts "# command=#{Shellwords.split(command).inspect}"
32
+ puts "# name=#{name}"
33
+ puts code_lines.map {|line, i| "#{"%4d" % i} #{line}" }.join
34
+
35
+ code = code_lines.map(&:first).join
36
+
37
+ puts ">>> Running..."
38
+ Dir.mktmpdir do |dir|
39
+ File.write(File.join(dir, name), code)
40
+ pid = spawn({ "BUNDLE_GEMFILE" => File.join(__dir__, "../Gemfile") },
41
+ *Shellwords.split(command),
42
+ chdir: dir)
43
+
44
+ _, status = Process.waitpid2(pid)
45
+
46
+ status.success? or raise "Failed to execute code: #{code_lines.join}"
47
+ end
48
+ end
49
+ end
data/lib/rbs.rb CHANGED
@@ -32,8 +32,10 @@ require "rbs/writer"
32
32
  require "rbs/prototype/rbi"
33
33
  require "rbs/prototype/rb"
34
34
  require "rbs/prototype/runtime"
35
+ require "rbs/type_name_resolver"
35
36
  require "rbs/environment_walker"
36
37
  require "rbs/vendorer"
38
+ require "rbs/validator"
37
39
 
38
40
  begin
39
41
  require "rbs/parser"
@@ -1,6 +1,9 @@
1
1
  module RBS
2
2
  module AST
3
3
  module Declarations
4
+ class Base
5
+ end
6
+
4
7
  class ModuleTypeParams
5
8
  attr_reader :params
6
9
 
@@ -77,7 +80,53 @@ module RBS
77
80
  end
78
81
  end
79
82
 
80
- class Class
83
+ module NestedDeclarationHelper
84
+ def each_member
85
+ if block_given?
86
+ members.each do |member|
87
+ if member.is_a?(Members::Base)
88
+ yield member
89
+ end
90
+ end
91
+ else
92
+ enum_for :each_member
93
+ end
94
+ end
95
+
96
+ def each_decl
97
+ if block_given?
98
+ members.each do |member|
99
+ if member.is_a?(Declarations::Base)
100
+ yield member
101
+ end
102
+ end
103
+ else
104
+ enum_for :each_decl
105
+ end
106
+ end
107
+ end
108
+
109
+ module MixinHelper
110
+ def each_mixin(&block)
111
+ if block_given?
112
+ @mixins ||= begin
113
+ members.select do |member|
114
+ case member
115
+ when Members::Include, Members::Extend, Members::Prepend
116
+ true
117
+ else
118
+ false
119
+ end
120
+ end
121
+ end
122
+ @mixins.each(&block)
123
+ else
124
+ enum_for :each_mixin
125
+ end
126
+ end
127
+ end
128
+
129
+ class Class < Base
81
130
  class Super
82
131
  attr_reader :name
83
132
  attr_reader :args
@@ -105,6 +154,9 @@ module RBS
105
154
  end
106
155
  end
107
156
 
157
+ include NestedDeclarationHelper
158
+ include MixinHelper
159
+
108
160
  attr_reader :name
109
161
  attr_reader :type_params
110
162
  attr_reader :members
@@ -151,7 +203,10 @@ module RBS
151
203
  end
152
204
  end
153
205
 
154
- class Module
206
+ class Module < Base
207
+ include NestedDeclarationHelper
208
+ include MixinHelper
209
+
155
210
  attr_reader :name
156
211
  attr_reader :type_params
157
212
  attr_reader :members
@@ -198,7 +253,7 @@ module RBS
198
253
  end
199
254
  end
200
255
 
201
- class Extension
256
+ class Extension < Base
202
257
  attr_reader :name
203
258
  attr_reader :type_params
204
259
  attr_reader :extension_name
@@ -245,7 +300,7 @@ module RBS
245
300
  end
246
301
  end
247
302
 
248
- class Interface
303
+ class Interface < Base
249
304
  attr_reader :name
250
305
  attr_reader :type_params
251
306
  attr_reader :members
@@ -288,7 +343,7 @@ module RBS
288
343
  end
289
344
  end
290
345
 
291
- class Alias
346
+ class Alias < Base
292
347
  attr_reader :name
293
348
  attr_reader :type
294
349
  attr_reader :annotations
@@ -327,7 +382,7 @@ module RBS
327
382
  end
328
383
  end
329
384
 
330
- class Constant
385
+ class Constant < Base
331
386
  attr_reader :name
332
387
  attr_reader :type
333
388
  attr_reader :location
@@ -363,7 +418,7 @@ module RBS
363
418
  end
364
419
  end
365
420
 
366
- class Global
421
+ class Global < Base
367
422
  attr_reader :name
368
423
  attr_reader :type
369
424
  attr_reader :location