rbs 0.8.0 → 0.12.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 (77) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +32 -0
  3. data/Gemfile +1 -0
  4. data/README.md +1 -1
  5. data/Rakefile +9 -4
  6. data/Steepfile +28 -0
  7. data/bin/steep +4 -0
  8. data/bin/test_runner.rb +10 -5
  9. data/docs/syntax.md +14 -1
  10. data/lib/rbs/ast/comment.rb +12 -0
  11. data/lib/rbs/ast/declarations.rb +15 -9
  12. data/lib/rbs/ast/members.rb +3 -8
  13. data/lib/rbs/buffer.rb +1 -1
  14. data/lib/rbs/cli.rb +66 -2
  15. data/lib/rbs/definition.rb +35 -16
  16. data/lib/rbs/definition_builder.rb +111 -68
  17. data/lib/rbs/environment.rb +24 -11
  18. data/lib/rbs/environment_loader.rb +55 -35
  19. data/lib/rbs/location.rb +14 -3
  20. data/lib/rbs/method_type.rb +5 -5
  21. data/lib/rbs/namespace.rb +14 -3
  22. data/lib/rbs/parser.y +8 -20
  23. data/lib/rbs/prototype/rb.rb +3 -5
  24. data/lib/rbs/prototype/rbi.rb +1 -4
  25. data/lib/rbs/prototype/runtime.rb +0 -4
  26. data/lib/rbs/substitution.rb +4 -3
  27. data/lib/rbs/test/hook.rb +1 -0
  28. data/lib/rbs/test/setup.rb +17 -12
  29. data/lib/rbs/test/setup_helper.rb +15 -0
  30. data/lib/rbs/test/tester.rb +59 -13
  31. data/lib/rbs/test/type_check.rb +43 -14
  32. data/lib/rbs/type_name.rb +18 -1
  33. data/lib/rbs/type_name_resolver.rb +10 -3
  34. data/lib/rbs/types.rb +27 -21
  35. data/lib/rbs/validator.rb +4 -0
  36. data/lib/rbs/variance_calculator.rb +8 -5
  37. data/lib/rbs/version.rb +1 -1
  38. data/lib/rbs/writer.rb +7 -3
  39. data/sig/annotation.rbs +26 -0
  40. data/sig/buffer.rbs +28 -0
  41. data/sig/builtin_names.rbs +41 -0
  42. data/sig/comment.rbs +26 -0
  43. data/sig/declarations.rbs +202 -0
  44. data/sig/definition.rbs +129 -0
  45. data/sig/definition_builder.rbs +95 -0
  46. data/sig/environment.rbs +94 -0
  47. data/sig/environment_loader.rbs +4 -0
  48. data/sig/location.rbs +52 -0
  49. data/sig/members.rbs +160 -0
  50. data/sig/method_types.rbs +40 -0
  51. data/sig/namespace.rbs +124 -0
  52. data/sig/polyfill.rbs +3 -0
  53. data/sig/rbs.rbs +3 -0
  54. data/sig/substitution.rbs +39 -0
  55. data/sig/type_name_resolver.rbs +24 -0
  56. data/sig/typename.rbs +70 -0
  57. data/sig/types.rbs +361 -0
  58. data/sig/util.rbs +13 -0
  59. data/sig/variance_calculator.rbs +35 -0
  60. data/stdlib/bigdecimal/big_decimal.rbs +887 -0
  61. data/stdlib/bigdecimal/math/big_math.rbs +142 -0
  62. data/stdlib/builtin/array.rbs +2 -1
  63. data/stdlib/builtin/builtin.rbs +0 -3
  64. data/stdlib/builtin/hash.rbs +1 -1
  65. data/stdlib/builtin/math.rbs +26 -26
  66. data/stdlib/builtin/struct.rbs +9 -10
  67. data/stdlib/date/date.rbs +1056 -0
  68. data/stdlib/date/date_time.rbs +582 -0
  69. data/stdlib/forwardable/forwardable.rbs +204 -0
  70. data/stdlib/json/json.rbs +6 -0
  71. data/stdlib/set/set.rbs +1 -1
  72. data/stdlib/uri/file.rbs +167 -0
  73. data/stdlib/uri/generic.rbs +875 -0
  74. data/stdlib/zlib/zlib.rbs +392 -0
  75. data/steep/Gemfile +3 -0
  76. data/steep/Gemfile.lock +55 -0
  77. metadata +39 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a2e86d5e87d89f97eed8e2674aa5f5035413179ba104a5cb265ab748268c51fe
4
- data.tar.gz: 9d58fa00413d5a334496ee688bbc72520e1911558f39ad2d01b180b790e5d894
3
+ metadata.gz: db07b9abb1ed59e789d6a13145e33503f20e37a908826c3c8ba8222f9cf79ec6
4
+ data.tar.gz: a42440c8542489fd70f24139f24e718b106caa99925a437857867141f730ed9a
5
5
  SHA512:
6
- metadata.gz: 328850c1f912cd7cc45e1c210140c098206f668c0400a817cde00e36dec1591ec235b5b6a1255b0e66d585745d4f6f7effeb09f28ae2a7536091852f9ba8bc89
7
- data.tar.gz: 96bc5adc81b98d723a98d20dcbeef13424fb0a4267272ff1ad6daaab5ef310f24c038f4e23793253beade1e55a00a6eece457697a3a4ec62413f08b7c42ace99
6
+ metadata.gz: 606289f49ac2d2934808add204997b7828708b05f2b3d60c10f8de6106cbca06527fd628de445511dfa537976fab551e878a45b5ab03ac41374cf242f90b6244
7
+ data.tar.gz: 5de0b5b93fd872a69fe25d62eaf72fba3fc4d93b57f04f5da311fc66d3b6eeebe53fb654cea4361da32124861ac21c1ad9547bf9e7c0012b6db704e98164a8d9
@@ -2,6 +2,38 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.12.0 (2020-09-15)
6
+
7
+ * Signature updates for `forwardable`, `struct`, `set`, `URI::Generic`, `URI::File`, and `BigDecimal`.
8
+ * Define `.new` methods from `initialize` included from modules [#390](https://github.com/ruby/rbs/pull/390)
9
+
10
+ ## 0.11.0 (2020-08-31)
11
+
12
+ * Signature update for `date/datetime` [#367](https://github.com/ruby/rbs/pull/367)
13
+ * Add test double support for runtime type checker [#380](https://github.com/ruby/rbs/pull/380)
14
+ * Add `rbs test` command for runtime type checking [#366](https://github.com/ruby/rbs/pull/366)
15
+ * Fix runtime type checking for record types [#365](https://github.com/ruby/rbs/pull/365)
16
+ * Improve EnvironmentLoader API [#370](https://github.com/ruby/rbs/pull/370)
17
+ * Allow overloading from super methods [#364](https://github.com/ruby/rbs/pull/364)
18
+
19
+ ## 0.10.0 (2020-08-10)
20
+
21
+ * Signature update for `Zlib`
22
+ * Make "no type checker installed" message a debug print [#363](https://github.com/ruby/rbs/pull/363)
23
+ * Print `...` for overloading method definitions [#362](https://github.com/ruby/rbs/pull/362)
24
+ * Allow missing method implementation in Ruby code [#359](https://github.com/ruby/rbs/pull/359)
25
+ * Runtime testing improvements [#356](https://github.com/ruby/rbs/pull/356)
26
+
27
+ ## 0.9.1 (2020-08-04)
28
+
29
+ * Ensure using Module#name [#354](https://github.com/ruby/rbs/pull/354)
30
+ * Fix runtime test setup [#353](https://github.com/ruby/rbs/pull/353)
31
+
32
+ ## 0.9.0 (2020-08-03)
33
+
34
+ * Fix signature validation [#351](https://github.com/ruby/rbs/pull/351), [#352](https://github.com/ruby/rbs/pull/352)
35
+ * Parsing performance improvement [#350](https://github.com/ruby/rbs/pull/350)
36
+
5
37
  ## 0.8.0 (2020-08-01)
6
38
 
7
39
  * Signature updates for `Enumerator` and `PTY`
data/Gemfile CHANGED
@@ -6,6 +6,7 @@ gemspec
6
6
  # Development dependencies
7
7
  gem "rake"
8
8
  gem "minitest"
9
+ gem "rspec"
9
10
  gem "racc"
10
11
  gem "rubocop"
11
12
  gem "rubocop-rubycw"
data/README.md CHANGED
@@ -123,7 +123,7 @@ puts singleton.methods[:gsub]
123
123
 
124
124
  ## Development
125
125
 
126
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
126
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
127
127
 
128
128
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
129
129
 
data/Rakefile CHANGED
@@ -1,5 +1,10 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rake/testtask"
3
+ require "rbconfig"
4
+
5
+ ruby = ENV["RUBY"] || RbConfig.ruby
6
+ rbs = File.join(__dir__, "exe/rbs")
7
+ bin = File.join(__dir__, "bin")
3
8
 
4
9
  Rake::TestTask.new(:test) do |t|
5
10
  t.libs << "test"
@@ -16,21 +21,21 @@ task :test_doc => :parser do
16
21
  `git ls-files -z`.split("\x0").select do |file| Pathname(file).extname == ".md" end
17
22
  end
18
23
 
19
- sh "ruby bin/run_in_md.rb #{files.join(" ")}"
24
+ sh "#{ruby} #{__dir__}/bin/run_in_md.rb #{files.join(" ")}"
20
25
  end
21
26
 
22
27
  task :validate => :parser do
23
- sh "rbs validate"
28
+ sh "#{ruby} #{rbs} validate"
24
29
 
25
30
  FileList["stdlib/*"].each do |path|
26
31
  next if path =~ %r{stdlib/builtin}
27
- sh "rbs -r#{File.basename(path)} validate"
32
+ sh "#{ruby} #{rbs} -r#{File.basename(path)} validate"
28
33
  end
29
34
  end
30
35
 
31
36
  FileList["test/stdlib/**/*_test.rb"].each do |test|
32
37
  multitask test => :parser do
33
- sh "ruby bin/test_runner.rb #{test}"
38
+ sh "#{ruby} -Ilib #{bin}/test_runner.rb #{test}"
34
39
  end
35
40
  multitask stdlib_test: test
36
41
  end
@@ -0,0 +1,28 @@
1
+ target :lib do
2
+ signature "sig"
3
+ check "lib"
4
+
5
+ vendor stdlib: "stdlib"
6
+ library "set", "pathname", "json", "logger"
7
+ end
8
+
9
+ # target :lib do
10
+ # signature "sig"
11
+ #
12
+ # check "lib" # Directory name
13
+ # check "Gemfile" # File name
14
+ # check "app/models/**/*.rb" # Glob
15
+ # # ignore "lib/templates/*.rb"
16
+ #
17
+ # # library "pathname", "set" # Standard libraries
18
+ # # library "strong_json" # Gems
19
+ # end
20
+
21
+ # target :spec do
22
+ # signature "sig", "sig-private"
23
+ #
24
+ # check "spec"
25
+ #
26
+ # # library "pathname", "set" # Standard libraries
27
+ # # library "rspec"
28
+ # end
@@ -0,0 +1,4 @@
1
+ #!/bin/sh
2
+
3
+ GEMFILE=$(cd $(dirname $0); pwd)/../steep/Gemfile
4
+ bundle exec --gemfile=${GEMFILE} steep $*
@@ -1,12 +1,17 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- RUBY_27 = Gem::Version.new(RUBY_VERSION).yield_self do |ruby_version|
4
- Gem::Version.new('2.7.0') <= ruby_version && ruby_version < Gem::Version.new("2.8.0")
3
+ $LOAD_PATH << File.join(__dir__, "../lib")
4
+
5
+ STDLIB_TEST = Gem::Version.new(RUBY_VERSION).yield_self do |ruby_version|
6
+ Gem::Version.new('2.7.0') <= ruby_version &&
7
+ ruby_version <= Gem::Version.new('2.8.0')
5
8
  end
6
9
 
7
- unless RUBY_27
8
- STDERR.puts "🚨🚨🚨 stdlib test requires Ruby 2.7 but RUBY_VERSION==#{RUBY_VERSION}, exiting... 🚨🚨🚨"
9
- exit
10
+ unless STDLIB_TEST
11
+ unless ENV["FORCE_STDLIB_TEST"]
12
+ STDERR.puts "🚨🚨🚨 stdlib test requires Ruby 2.7 or later but RUBY_VERSION==#{RUBY_VERSION}, exiting... 🚨🚨🚨"
13
+ exit
14
+ end
10
15
  end
11
16
 
12
17
  ARGV.each do |arg|
@@ -212,7 +212,7 @@ _method-type_ ::= `(` _parameters_ `) ->` _type_
212
212
 
213
213
  _parameters_ ::= _required-positionals_ _optional-positionals_ _rest-positional_ _trailing-positionals_ _keywords_
214
214
 
215
- _paramater_ ::= _type_ _var-name_ # Parameter with var name
215
+ _parameter_ ::= _type_ _var-name_ # Parameter with var name
216
216
  | _type_ # Parameter without var name
217
217
  _required-positionals_ ::= _parameter_ `,` ...
218
218
  _optional-positionals_ ::= `?` _parameter_ `,` ...
@@ -529,3 +529,16 @@ You can declare a global variable.
529
529
  $LOAD_PATH: Array[String]
530
530
  ```
531
531
 
532
+ ### Comments
533
+
534
+ You can write single line comments. Comments must be on their own line. Comments can lead with whitespace.
535
+
536
+ ```
537
+ # This if interface Foo
538
+ # Usage of Foo is bar
539
+ interface _Foo
540
+ # New foo is a method
541
+ # it will return foo.
542
+ def new: () -> Foo
543
+ end
544
+ ```
@@ -22,6 +22,18 @@ module RBS
22
22
  def to_json(*a)
23
23
  { string: string, location: location }.to_json(*a)
24
24
  end
25
+
26
+ def concat(string:, location:)
27
+ @string.concat string
28
+
29
+ if loc = @location
30
+ loc.concat location
31
+ else
32
+ @location = location
33
+ end
34
+
35
+ self
36
+ end
25
37
  end
26
38
  end
27
39
  end
@@ -7,7 +7,7 @@ module RBS
7
7
  class ModuleTypeParams
8
8
  attr_reader :params
9
9
 
10
- TypeParam = Struct.new(:name, :variance, :skip_validation, keyword_init: true) do
10
+ TypeParam = _ = Struct.new(:name, :variance, :skip_validation, keyword_init: true) do
11
11
  def to_json(*a)
12
12
  {
13
13
  name: name,
@@ -47,7 +47,11 @@ module RBS
47
47
  end
48
48
 
49
49
  def each(&block)
50
- params.each(&block)
50
+ if block
51
+ params.each(&block)
52
+ else
53
+ params.each
54
+ end
51
55
  end
52
56
 
53
57
  def self.empty
@@ -55,11 +59,13 @@ module RBS
55
59
  end
56
60
 
57
61
  def variance(name)
58
- self[name].variance
62
+ var = self[name] or raise
63
+ var.variance
59
64
  end
60
65
 
61
66
  def skip_validation?(name)
62
- self[name].skip_validation
67
+ var = self[name] or raise
68
+ var.skip_validation
63
69
  end
64
70
 
65
71
  def empty?
@@ -85,7 +91,7 @@ module RBS
85
91
  if block_given?
86
92
  members.each do |member|
87
93
  if member.is_a?(Members::Base)
88
- yield member
94
+ yield(_ = member)
89
95
  end
90
96
  end
91
97
  else
@@ -96,8 +102,8 @@ module RBS
96
102
  def each_decl
97
103
  if block_given?
98
104
  members.each do |member|
99
- if member.is_a?(Declarations::Base)
100
- yield member
105
+ if member.is_a?(Base)
106
+ yield(_ = member)
101
107
  end
102
108
  end
103
109
  else
@@ -108,9 +114,9 @@ module RBS
108
114
 
109
115
  module MixinHelper
110
116
  def each_mixin(&block)
111
- if block_given?
117
+ if block
112
118
  @mixins ||= begin
113
- members.select do |member|
119
+ _ = members.select do |member|
114
120
  case member
115
121
  when Members::Include, Members::Extend, Members::Prepend
116
122
  true
@@ -11,17 +11,15 @@ module RBS
11
11
  attr_reader :annotations
12
12
  attr_reader :location
13
13
  attr_reader :comment
14
- attr_reader :attributes
15
14
  attr_reader :overload
16
15
 
17
- def initialize(name:, kind:, types:, annotations:, location:, comment:, attributes:, overload:)
16
+ def initialize(name:, kind:, types:, annotations:, location:, comment:, overload:)
18
17
  @name = name
19
18
  @kind = kind
20
19
  @types = types
21
20
  @annotations = annotations
22
21
  @location = location
23
22
  @comment = comment
24
- @attributes = attributes
25
23
  @overload = overload
26
24
  end
27
25
 
@@ -30,14 +28,13 @@ module RBS
30
28
  other.name == name &&
31
29
  other.kind == kind &&
32
30
  other.types == types &&
33
- other.attributes == attributes &&
34
31
  other.overload == overload
35
32
  end
36
33
 
37
34
  alias eql? ==
38
35
 
39
36
  def hash
40
- self.class.hash ^ name.hash ^ kind.hash ^ types.hash ^ attributes.hash ^ overload.hash
37
+ self.class.hash ^ name.hash ^ kind.hash ^ types.hash ^ overload.hash
41
38
  end
42
39
 
43
40
  def instance?
@@ -52,7 +49,7 @@ module RBS
52
49
  overload
53
50
  end
54
51
 
55
- def update(name: self.name, kind: self.kind, types: self.types, annotations: self.annotations, location: self.location, comment: self.comment, attributes: self.attributes, overload: self.overload)
52
+ def update(name: self.name, kind: self.kind, types: self.types, annotations: self.annotations, location: self.location, comment: self.comment, overload: self.overload)
56
53
  self.class.new(
57
54
  name: name,
58
55
  kind: kind,
@@ -60,7 +57,6 @@ module RBS
60
57
  annotations: annotations,
61
58
  location: location,
62
59
  comment: comment,
63
- attributes: attributes,
64
60
  overload: overload
65
61
  )
66
62
  end
@@ -73,7 +69,6 @@ module RBS
73
69
  annotations: annotations,
74
70
  location: location,
75
71
  comment: comment,
76
- attributes: attributes,
77
72
  overload: overload
78
73
  }.to_json(*a)
79
74
  end
@@ -23,7 +23,7 @@ module RBS
23
23
 
24
24
  def pos_to_loc(pos)
25
25
  index = ranges.bsearch_index do |range|
26
- pos < range.end
26
+ pos < range.end ? true : false
27
27
  end
28
28
 
29
29
  if index
@@ -1,4 +1,5 @@
1
1
  require "optparse"
2
+ require "shellwords"
2
3
 
3
4
  module RBS
4
5
  class CLI
@@ -36,7 +37,7 @@ module RBS
36
37
  @stderr = stderr
37
38
  end
38
39
 
39
- COMMANDS = [:ast, :list, :ancestors, :methods, :method, :validate, :constant, :paths, :prototype, :vendor, :parse]
40
+ COMMANDS = [:ast, :list, :ancestors, :methods, :method, :validate, :constant, :paths, :prototype, :vendor, :parse, :test]
40
41
 
41
42
  def library_parse(opts, options:)
42
43
  opts.on("-r LIBRARY", "Load RBS files of the library") do |lib|
@@ -413,6 +414,7 @@ EOU
413
414
  env.constant_decls.each do |name, const|
414
415
  stdout.puts "Validating constant: `#{name}`..."
415
416
  validator.validate_type const.decl.type, context: const.context
417
+ builder.ensure_namespace!(name.namespace, location: const.decl.location)
416
418
  end
417
419
 
418
420
  env.global_decls.each do |name, global|
@@ -422,7 +424,9 @@ EOU
422
424
 
423
425
  env.alias_decls.each do |name, decl|
424
426
  stdout.puts "Validating alias: `#{name}`..."
425
- validator.validate_type decl.decl.type, context: decl.context
427
+ builder.expand_alias(name).tap do |type|
428
+ validator.validate_type type, context: [Namespace.root]
429
+ end
426
430
  end
427
431
  end
428
432
 
@@ -747,5 +751,65 @@ Examples:
747
751
  TypeName.new(name: last, namespace: namespace.parent)
748
752
  end
749
753
  end
754
+
755
+ def test_opt options
756
+ opt_string = options.dirs.map { |dir| "-I #{Shellwords.escape(dir)}"}.concat(options.libs.map { |lib| "-r#{Shellwords.escape(lib)}"}).join(' ')
757
+ opt_string.empty? ? nil : opt_string
758
+ end
759
+
760
+ def run_test(args, options)
761
+ unchecked_classes = []
762
+ targets = []
763
+ sample_size = nil
764
+ double_suite = nil
765
+
766
+ (opts = OptionParser.new do |opts|
767
+ opts.banner = <<EOB
768
+ Usage: rbs [rbs options...] test [test options...] COMMAND
769
+
770
+ Examples:
771
+
772
+ $ rbs test rake test
773
+ $ rbs --log-level=debug test --target SomeModule::* rspec
774
+ $ rbs test --target SomeModule::* --target AnotherModule::* --target SomeClass rake test
775
+
776
+ Options:
777
+ EOB
778
+ opts.on("--target TARGET", "Sets the runtime test target") do |target|
779
+ targets << target
780
+ end
781
+
782
+ opts.on("--sample-size SAMPLE_SIZE", "Sets the sample size") do |size|
783
+ sample_size = size
784
+ end
785
+
786
+ opts.on("--unchecked-class UNCHECKED_CLASS", "Sets the class that would not be checked") do |unchecked_class|
787
+ unchecked_classes << unchecked_class
788
+ end
789
+
790
+ opts.on("--double-suite DOUBLE_SUITE", "Sets the double suite in use (currently supported: rspec | minitest)") do |suite|
791
+ double_suite = suite
792
+ end
793
+
794
+ end).order!(args)
795
+
796
+ if args.length.zero?
797
+ stdout.puts opts.help
798
+ exit 1
799
+ end
800
+
801
+ env_hash = {
802
+ 'RUBYOPT' => "#{ENV['RUBYOPT']} -rrbs/test/setup",
803
+ 'RBS_TEST_OPT' => test_opt(options),
804
+ 'RBS_TEST_LOGLEVEL' => RBS.logger_level,
805
+ 'RBS_TEST_SAMPLE_SIZE' => sample_size,
806
+ 'RBS_TEST_DOUBLE_SUITE' => double_suite,
807
+ 'RBS_TEST_UNCHECKED_CLASSES' => (unchecked_classes.join(',') unless unchecked_classes.empty?),
808
+ 'RBS_TEST_TARGET' => (targets.join(',') unless targets.empty?)
809
+ }
810
+
811
+ system(env_hash, *args)
812
+ $?
813
+ end
750
814
  end
751
815
  end
@@ -45,24 +45,41 @@ module RBS
45
45
  def update(type: self.type, member: self.member, defined_in: self.defined_in, implemented_in: self.implemented_in)
46
46
  TypeDef.new(type: type, member: member, defined_in: defined_in, implemented_in: implemented_in)
47
47
  end
48
+
49
+ def overload?
50
+ case mem = member
51
+ when AST::Members::MethodDefinition
52
+ mem.overload?
53
+ else
54
+ false
55
+ end
56
+ end
48
57
  end
49
58
 
50
59
  attr_reader :super_method
51
60
  attr_reader :defs
52
61
  attr_reader :accessibility
62
+ attr_reader :extra_annotations
53
63
 
54
- def initialize(super_method:, defs:, accessibility:)
64
+ def initialize(super_method:, defs:, accessibility:, annotations: [])
55
65
  @super_method = super_method
56
66
  @defs = defs
57
67
  @accessibility = accessibility
68
+ @extra_annotations = annotations
58
69
  end
59
70
 
60
71
  def defined_in
61
- @defined_in ||= defs.last.defined_in
72
+ @defined_in ||= begin
73
+ last_def = defs.last or raise
74
+ last_def.defined_in
75
+ end
62
76
  end
63
77
 
64
78
  def implemented_in
65
- @implemented_in ||= defs.last.implemented_in
79
+ @implemented_in ||= begin
80
+ last_def = defs.last or raise
81
+ last_def.implemented_in
82
+ end
66
83
  end
67
84
 
68
85
  def method_types
@@ -70,16 +87,15 @@ module RBS
70
87
  end
71
88
 
72
89
  def comments
73
- @comments ||= defs.map(&:comment).compact
90
+ @comments ||= _ = defs.map(&:comment).compact
74
91
  end
75
92
 
76
93
  def annotations
77
- @annotations ||= defs.flat_map(&:annotations)
94
+ @annotations ||= @extra_annotations + defs.flat_map(&:annotations)
78
95
  end
79
96
 
80
- # @deprecated
81
- def attributes
82
- []
97
+ def members
98
+ @members ||= defs.map(&:member).uniq
83
99
  end
84
100
 
85
101
  def public?
@@ -116,8 +132,8 @@ module RBS
116
132
  end
117
133
 
118
134
  module Ancestor
119
- Instance = Struct.new(:name, :args, keyword_init: true)
120
- Singleton = Struct.new(:name, keyword_init: true)
135
+ Instance = _ = Struct.new(:name, :args, keyword_init: true)
136
+ Singleton = _ = Struct.new(:name, keyword_init: true)
121
137
  end
122
138
 
123
139
  class InstanceAncestors
@@ -209,7 +225,10 @@ module RBS
209
225
  end
210
226
 
211
227
  def interface?
212
- entry.is_a?(Environment::SingleEntry) && entry.decl.is_a?(AST::Declarations::Interface)
228
+ case en = entry
229
+ when Environment::SingleEntry
230
+ en.decl.is_a?(AST::Declarations::Interface)
231
+ end
213
232
  end
214
233
 
215
234
  def class_type?
@@ -229,16 +248,16 @@ module RBS
229
248
  end
230
249
 
231
250
  def type_params_decl
232
- case entry
251
+ case en = entry
233
252
  when Environment::ClassEntry, Environment::ModuleEntry
234
- entry.type_params
253
+ en.type_params
235
254
  when Environment::SingleEntry
236
- entry.decl.type_params
255
+ en.decl.type_params
237
256
  end
238
257
  end
239
258
 
240
259
  def sub(s)
241
- definition = self.class.new(type_name: type_name, self_type: self_type.sub(s), ancestors: ancestors, entry: entry)
260
+ definition = self.class.new(type_name: type_name, self_type: _ = self_type.sub(s), ancestors: ancestors, entry: entry)
242
261
 
243
262
  definition.methods.merge!(methods.transform_values {|method| method.sub(s) })
244
263
  definition.instance_variables.merge!(instance_variables.transform_values {|v| v.sub(s) })
@@ -258,7 +277,7 @@ module RBS
258
277
  end
259
278
 
260
279
  def each_type(&block)
261
- if block_given?
280
+ if block
262
281
  methods.each_value do |method|
263
282
  if method.defined_in == type_name
264
283
  method.method_types.each do |method_type|