rbs 0.8.0 → 0.12.0

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