rbs_rails 0.4.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +1 -0
  3. data/.github/workflows/ci.yml +18 -0
  4. data/.gitignore +3 -1
  5. data/.gitmodules +0 -0
  6. data/CHANGELOG.md +13 -0
  7. data/Gemfile +2 -2
  8. data/README.md +24 -43
  9. data/Rakefile +2 -1
  10. data/Steepfile +12 -1
  11. data/bin/add-type-params.rb +2 -1
  12. data/bin/gem_rbs +94 -0
  13. data/bin/postprocess.rb +1 -1
  14. data/bin/rbs +29 -2
  15. data/bin/rbs-prototype-rb.rb +59 -6
  16. data/lib/rbs_rails.rb +4 -0
  17. data/lib/rbs_rails/active_record.rb +74 -46
  18. data/lib/rbs_rails/dependency_builder.rb +43 -0
  19. data/lib/rbs_rails/rake_task.rb +73 -0
  20. data/lib/rbs_rails/util.rb +25 -0
  21. data/lib/rbs_rails/version.rb +1 -1
  22. data/rbs_rails.gemspec +3 -2
  23. data/sig/fileutils.rbs +1 -0
  24. data/sig/rake.rbs +6 -0
  25. data/sig/rbs_rails/active_record.rbs +8 -2
  26. data/sig/rbs_rails/dependency_builder.rbs +9 -0
  27. data/sig/rbs_rails/rake_task.rbs +26 -0
  28. data/sig/rbs_rails/util.rbs +11 -0
  29. metadata +30 -46
  30. data/.travis.yml +0 -11
  31. data/assets/sig/action_controller.rbs +0 -49
  32. data/assets/sig/action_mailer.rbs +0 -8
  33. data/assets/sig/active_record.rbs +0 -137
  34. data/assets/sig/builtin.rbs +0 -7
  35. data/assets/sig/capybara.rbs +0 -14
  36. data/assets/sig/concurrent.rbs +0 -4
  37. data/assets/sig/erb.rbs +0 -4
  38. data/assets/sig/erubi.rbs +0 -4
  39. data/assets/sig/generated/actionpack.rbs +0 -11831
  40. data/assets/sig/generated/actionview.rbs +0 -10591
  41. data/assets/sig/generated/activejob.rbs +0 -1920
  42. data/assets/sig/generated/activemodel.rbs +0 -4214
  43. data/assets/sig/generated/activerecord-meta-programming.rbs +0 -98
  44. data/assets/sig/generated/activerecord.rbs +0 -24602
  45. data/assets/sig/generated/activesupport.rbs +0 -12613
  46. data/assets/sig/generated/railties.rbs +0 -4687
  47. data/assets/sig/i18n.rbs +0 -4
  48. data/assets/sig/libxml.rbs +0 -10
  49. data/assets/sig/minitest.rbs +0 -13
  50. data/assets/sig/nokogiri.rbs +0 -8
  51. data/assets/sig/patches/README.md +0 -4
  52. data/assets/sig/patches/for_actionpack.rbs +0 -74
  53. data/assets/sig/patches/for_actionview.rbs +0 -19
  54. data/assets/sig/patches/for_activemodel.rbs +0 -11
  55. data/assets/sig/patches/for_activerecord.rbs +0 -84
  56. data/assets/sig/patches/for_activesupport.rbs +0 -48
  57. data/assets/sig/patches/for_railties.rbs +0 -30
  58. data/assets/sig/pg.rbs +0 -5
  59. data/assets/sig/que.rbs +0 -4
  60. data/assets/sig/queue_classic.rbs +0 -4
  61. data/assets/sig/racc.rbs +0 -4
  62. data/assets/sig/rack-test.rbs +0 -6
  63. data/assets/sig/rack.rbs +0 -47
  64. data/assets/sig/rails.rbs +0 -14
  65. data/assets/sig/rdoc.rbs +0 -9
  66. data/assets/sig/sidekiq.rbs +0 -4
  67. data/assets/sig/sneakers.rbs +0 -4
  68. data/assets/sig/stdlib.rbs +0 -24
  69. data/assets/sig/sucker_punch.rbs +0 -4
  70. data/assets/sig/thor.rbs +0 -12
  71. data/assets/sig/tzinfo.rbs +0 -4
  72. data/bin/generate_rbs_from_rails_source_code.rb +0 -195
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 16709127e339f2c71c00ad11ac8ed13fa0dae3090c2ee30105486acd2cde536e
4
- data.tar.gz: 70464319628ea31b6ba77c958be4e335fcfefa6f55b3908ef168578a5bc4a03e
3
+ metadata.gz: 34709bd1892db293d9371b2574c97f5144d97f8b2de661072d7f65fb0616f971
4
+ data.tar.gz: 68f8207b59c550a6f5e6485ee322c38141154b47026c4d50c6bfe3cee9270494
5
5
  SHA512:
6
- metadata.gz: 3a26bb616fd9ff5a174c089afdc2f5283c182abe3868dd6fab1b25ca16c7f447c21520915d131b84e00a25e800dca8ca3ff5b5d2c093ac65fab924dd5424221b
7
- data.tar.gz: 52d257af8544a3639a3ffd98f3f0917fc5dd503e4682951cce3391ceed94bedf5d9eca1b0cd86b57e67fdc7d90093cf0a5acbc089c744e8bba5a49f38bd19364
6
+ metadata.gz: 01d91fa0f2aaeed8dd4614ec59f5604b125684ed63325f6edbb30c29db62e2ae60cffd450a28b0ef5ec44f32570bb1a25fdbb70230060def0a4ee73fb714ab0f
7
+ data.tar.gz: 535c957a38bc5644be6e83ccf1bf439a1830110a3355b4dfd4b84453f42d5975a506d85166ac53230d62af207765e1c4cab2f3de0b7564c97c084188e7726304
@@ -0,0 +1 @@
1
+ gem_rbs/gems/* linguist-generated=true
@@ -0,0 +1,18 @@
1
+ name: CI
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ test:
7
+ strategy:
8
+ fail-fast: false
9
+ matrix:
10
+ ruby: [2.6, 2.7, '3.0']
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v2
14
+ - uses: ruby/setup-ruby@v1
15
+ with:
16
+ ruby-version: ${{ matrix.ruby }}
17
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
18
+ - run: bundle exec rake
data/.gitignore CHANGED
@@ -7,4 +7,6 @@
7
7
  /spec/reports/
8
8
  /tmp/
9
9
  /Gemfile.lock
10
- /test/sig
10
+ /test/app/sig/rbs_rails
11
+ /test/app/sig/app
12
+ /test/app/sig/path_helpers.rbs
File without changes
@@ -0,0 +1,13 @@
1
+ # Change log
2
+
3
+ ## master (unreleased)
4
+
5
+ ## 0.8.0 (2020-12-31)
6
+
7
+ * **[BREAKING]** Move RBS files that are copied by `rbs_rails:copy_signature_files` task to [ruby/gem_rbs](https://github.com/ruby/gem_rbs) repository [#90](https://github.com/pocke/rbs_rails/pull/90)
8
+ * Allow all kinds of argument for scope [#89](https://github.com/pocke/rbs_rails/pull/89)
9
+
10
+ ## 0.7.0 (2020-12-28)
11
+
12
+ * **[BREAKING]** Re-structure signature directory. [#86](https://github.com/pocke/rbs_rails/pull/86)
13
+ * Generate ActiveRecord models with namespaces and superclasses. [#87](https://github.com/pocke/rbs_rails/pull/87)
data/Gemfile CHANGED
@@ -4,6 +4,6 @@ source "https://rubygems.org"
4
4
  gemspec
5
5
 
6
6
  gem "rake", "~> 12.0"
7
- gem 'rbs', '>= 0.14.0'
8
- gem 'steep', '>= 0.34.0'
7
+ gem 'rbs', '1.0.0'
8
+ gem 'steep', '>= 0.34.0', git: 'https://github.com/soutaro/steep.git'
9
9
  gem 'minitest'
data/README.md CHANGED
@@ -7,7 +7,7 @@ RBS files generator for Ruby on Rails.
7
7
  Add this line to your application's Gemfile:
8
8
 
9
9
  ```ruby
10
- gem 'rbs_rails'
10
+ gem 'rbs_rails', require: false
11
11
  ```
12
12
 
13
13
  And then execute:
@@ -20,56 +20,22 @@ Or install it yourself as:
20
20
 
21
21
  ## Usage
22
22
 
23
- ### For Active Record models
24
-
25
- It has two tasks.
26
-
27
- * `copy_signature_files`: Copy type definition files for Rails from rbs_rails.
28
- * `generate_rbs_for_model`: Generate RBS files from model classes.
23
+ Put the following code to `lib/tasks/rbs.rake`.
29
24
 
30
25
  ```ruby
31
- # Rakefile
32
-
33
- task copy_signature_files: :environment do
34
- require 'rbs_rails'
35
-
36
- to = Rails.root.join('sig/rbs_rails/')
37
- to.mkpath unless to.exist?
38
- RbsRails.copy_signatures(to: to)
39
- end
40
-
41
- task generate_rbs_for_model: :environment do
42
- require 'rbs_rails'
43
-
44
- out_dir = Rails.root / 'sig'
45
- out_dir.mkdir unless out_dir.exist?
46
-
47
- Rails.application.eager_load!
26
+ require 'rbs_rails/rake_task'
48
27
 
49
- ActiveRecord::Base.descendants.each do |klass|
50
- next if klass.abstract_class?
28
+ RbsRails::RakeTask.new
29
+ ```
51
30
 
52
- path = out_dir / "app/models/#{klass.name.underscore}.rbs"
53
- FileUtils.mkdir_p(path.dirname)
31
+ Then, the following three tasks are available.
54
32
 
55
- sig = RbsRails::ActiveRecord.class_to_rbs(klass)
56
- path.write sig
57
- end
58
- end
59
- ```
33
+ * `rbs_rails:generate_rbs_for_models`: Generate RBS files for Active Record models
34
+ * `rbs_rails:generate_rbs_for_path_helpers`: Generate RBS files for path helpers
35
+ * `rbs_rails:all`: Execute all tasks of RBS Rails
60
36
 
61
- ### For path helpers
62
37
 
63
- ```ruby
64
- # Rakefile
65
38
 
66
- task generate_rbs_for_path_helpers: :environment do
67
- require 'rbs_rails'
68
- out_path = Rails.root.join 'sig/path_helpers.rbs'
69
- rbs = RbsRails::PathHelpers.generate
70
- out_path.write rbs
71
- end
72
- ```
73
39
 
74
40
  ### Steep integration
75
41
 
@@ -83,13 +49,28 @@ target :app do
83
49
 
84
50
  check 'app'
85
51
 
52
+ repo_path "path/to/rbs_repo"
53
+
86
54
  library 'pathname'
87
55
  library 'logger'
88
56
  library 'mutex_m'
89
57
  library 'date'
58
+ library 'monitor'
59
+ library 'singleton'
60
+ library 'tsort'
61
+
62
+ library 'activesupport'
63
+ library 'actionpack'
64
+ library 'activejob'
65
+ library 'activemodel'
66
+ library 'actionview'
67
+ library 'activerecord'
68
+ library 'railties'
90
69
  end
91
70
  ```
92
71
 
72
+ You need to put RBS repo to `path/to/rbs_repo`. See https://github.com/ruby/gem_rbs
73
+
93
74
  ## Development
94
75
 
95
76
  After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
data/Rakefile CHANGED
@@ -9,7 +9,8 @@ task :steep do
9
9
  end
10
10
 
11
11
  task :rbs_validate do
12
- sh 'bin/rbs validate --silent'
12
+ rbs = Pathname(__dir__).join('bin/rbs').to_s
13
+ sh "ruby #{rbs} validate --silent"
13
14
  end
14
15
 
15
16
  Rake::TestTask.new do |test|
data/Steepfile CHANGED
@@ -3,10 +3,21 @@ target :lib do
3
3
  signature 'assets/sig'
4
4
 
5
5
  check "lib" # Directory name
6
+ repo_path ENV['RBS_REPO_DIR'] || './gem_rbs/gems'
6
7
 
7
8
  library "pathname"
8
9
  library "logger"
9
10
  library "mutex_m"
10
11
  library "date"
11
- # library "strong_json" # Gems
12
+ library 'monitor'
13
+ library 'singleton'
14
+ library 'tsort'
15
+
16
+ library 'activesupport'
17
+ library 'actionpack'
18
+ library 'activejob'
19
+ library 'activemodel'
20
+ library 'actionview'
21
+ library 'activerecord'
22
+ library 'railties'
12
23
  end
@@ -4,7 +4,7 @@ require 'bundler/inline'
4
4
 
5
5
  gemfile do
6
6
  source 'https://rubygems.org'
7
- gem 'rbs', '>= 0.16'
7
+ gem 'rbs', '1.0.0'
8
8
  end
9
9
 
10
10
  require 'rbs'
@@ -16,6 +16,7 @@ end
16
16
  def env
17
17
  @env ||= begin
18
18
  loader = RBS::EnvironmentLoader.new()
19
+ loader.add(library: 'tsort')
19
20
  RBS::Environment.from_loader(loader).resolve_type_names
20
21
  end
21
22
  end
@@ -0,0 +1,94 @@
1
+ #!ruby
2
+
3
+ require 'net/http'
4
+ require 'json'
5
+ require 'securerandom'
6
+ require 'pathname'
7
+
8
+ TOKEN = ENV.fetch('GITHUB_ACCESS_TOKEN')
9
+ VERSION = "6.0.3.2"
10
+
11
+ def req(query)
12
+ http = Net::HTTP.new("api.github.com", 443)
13
+ http.use_ssl = true
14
+ header = {
15
+ "Authorization" => "Bearer #{TOKEN}",
16
+ 'Content-Type' => 'application/json',
17
+ 'User-Agent' => 'gem_rbs client',
18
+ }
19
+ resp = http.request_post('/graphql', JSON.generate(query), header)
20
+ JSON.parse(resp.body, symbolize_names: true).tap do |content|
21
+ raise content[:errors].inspect if content[:errors]
22
+ end
23
+ end
24
+
25
+ class QueryBuilder
26
+ attr_reader :variables
27
+
28
+ def initialize
29
+ @queries = []
30
+ @variables = {}
31
+ end
32
+
33
+ def add(query, variables)
34
+ query = query.dup
35
+ variables = variables.transform_keys do |key|
36
+ next key unless @variables.key?(key)
37
+
38
+ new_key = key + '_' + SecureRandom.hex(8)
39
+ query.gsub!(key, new_key)
40
+ new_key
41
+ end
42
+
43
+ @queries << query
44
+ @variables.merge!(variables)
45
+ end
46
+
47
+ def query
48
+ # TODO: Allow non-String type for variables
49
+ "query(#{variables.keys.map { |v| "$#{v}: String!" }.join(',')}) { #{@queries.join("\n")} }"
50
+ end
51
+ end
52
+
53
+ gems = %w[activesupport actionpack activejob activemodel actionview activerecord railties]
54
+
55
+ builder = QueryBuilder.new
56
+ gems.each do |gem|
57
+ path = "main:gems/#{gem}/#{VERSION}"
58
+ builder.add(<<~GRAPHQL, { 'path' => path })
59
+ #{gem}:repository(owner: "ruby", name: "gem_rbs") {
60
+ object(expression: $path) {
61
+ ... on Tree {
62
+ entries {
63
+ name
64
+ object {
65
+ ... on Blob {
66
+ isTruncated
67
+ text
68
+ }
69
+ }
70
+ }
71
+ }
72
+ }
73
+ }
74
+ GRAPHQL
75
+ end
76
+
77
+ resp = req(query: builder.query, variables: builder.variables)
78
+
79
+ resp[:data].each do |gem_name, gem_value|
80
+ gem_value.dig(:object, :entries).each do |entry|
81
+ fname = entry[:name]
82
+ if fname.end_with?('.rbs')
83
+ content =
84
+ if entry.dig(:object, :isTruncated)
85
+ `curl -H 'Accept: application/vnd.github.v3.raw' -H Authorization: token #{TOKEN} https://api.github.com/repos/ruby/gem_rbs/contents/gems/#{gem_name}/#{VERSION}/#{fname}`
86
+ else
87
+ entry.dig(:object, :text)
88
+ end
89
+ dir = Pathname("gem_rbs/gems/#{gem_name}/#{VERSION}")
90
+ dir.mkpath
91
+ dir.join(fname).write(content)
92
+ end
93
+ end
94
+ end
@@ -6,7 +6,7 @@ require 'bundler/inline'
6
6
 
7
7
  gemfile do
8
8
  source 'https://rubygems.org'
9
- gem 'rbs', '>= 0.16'
9
+ gem 'rbs', '1.0.0'
10
10
  end
11
11
 
12
12
  require 'rbs'
data/bin/rbs CHANGED
@@ -1,3 +1,30 @@
1
- #!/bin/bash
1
+ #!ruby
2
+
3
+ require 'pathname'
4
+ root = Pathname(__dir__) / '../'
5
+
6
+ def v(require)
7
+ if v = ENV['RAILS_VERSION']
8
+ "#{require}:#{v}"
9
+ else
10
+ require
11
+ end
12
+ end
13
+
14
+ def repo
15
+ ENV['RBS_REPO_DIR'] || Pathname(__dir__).join('../gem_rbs/gems').to_s
16
+ end
17
+
18
+ exec(
19
+ 'rbs',
20
+ # Require stdlibs
21
+ '-rlogger', '-rpathname', '-rmutex_m', '-rdate', '-rmonitor', '-rsingleton', '-rtsort',
22
+ "--repo=#{repo}",
23
+ # Require Rails libraries
24
+ v('-ractivesupport'), v('-ractionpack'), v('-ractivejob'), v('-ractivemodel'), v('-ractionview'), v('-ractiverecord'), v('-rrailties'),
25
+ # Load signatures that are bundled in rbs_rails
26
+ '-I' + root.join('sig').to_s, '-I' + root.join('assets/sig').to_s,
27
+ # Expand arguments
28
+ *ARGV,
29
+ )
2
30
 
3
- rbs -rlogger -rpathname -rmutex_m -rdate -Isig -Iassets/sig $@
@@ -17,7 +17,7 @@ using Module.new {
17
17
  end
18
18
  end
19
19
 
20
- def process_class_methods(node, decls:, comments:, singleton:)
20
+ def process_class_methods(node, decls:, comments:, context:)
21
21
  return false unless node.type == :ITER
22
22
 
23
23
  fcall = node.children[0]
@@ -37,13 +37,13 @@ using Module.new {
37
37
  decls.push mod
38
38
 
39
39
  each_node [node.children[1]] do |child|
40
- process child, decls: mod.members, comments: comments, singleton: false
40
+ process child, decls: mod.members, comments: comments, context: RBS::Prototype::RB::Context.initial
41
41
  end
42
42
 
43
43
  true
44
44
  end
45
45
 
46
- def process_struct_new(node, decls:, comments:, singleton:)
46
+ def process_struct_new(node, decls:, comments:, context:)
47
47
  return unless node.type == :CDECL
48
48
 
49
49
  name, *_, rhs = node.children
@@ -68,6 +68,7 @@ using Module.new {
68
68
  kls.members << RBS::AST::Members::AttrAccessor.new(
69
69
  name: f.children.first,
70
70
  type: untyped,
71
+ kind: :instance,
71
72
  ivar_name: false,
72
73
  annotations: [],
73
74
  location: nil,
@@ -78,13 +79,65 @@ using Module.new {
78
79
 
79
80
  if body
80
81
  each_node [body] do |child|
81
- process child, decls: kls.members, comments: comments, singleton: false
82
+ process child, decls: kls.members, comments: comments, context: RBS::Prototype::RB::Context.initial
82
83
  end
83
84
  end
84
85
 
85
86
  true
86
87
  end
87
88
 
89
+ def process_attr_internal(node, decls:, comments:, context:)
90
+ case node.type
91
+ when :FCALL, :VCALL
92
+ args = node.children[1]&.children || []
93
+
94
+ case node.children[0]
95
+ when :attr_internal_reader
96
+ args.each do |arg|
97
+ if arg && (name = literal_to_symbol(arg))
98
+ decls << RBS::AST::Members::AttrReader.new(
99
+ name: name,
100
+ ivar_name: :"@_#{name}",
101
+ type: RBS::Types::Bases::Any.new(location: nil),
102
+ kind: context.attribute_kind,
103
+ location: nil,
104
+ comment: comments[node.first_lineno - 1],
105
+ annotations: []
106
+ )
107
+ end
108
+ end
109
+ when :attr_internal_writer
110
+ args.each do |arg|
111
+ if arg && (name = literal_to_symbol(arg))
112
+ decls << RBS::AST::Members::AttrWriter.new(
113
+ name: name,
114
+ ivar_name: :"@_#{name}",
115
+ type: RBS::Types::Bases::Any.new(location: nil),
116
+ kind: context.attribute_kind,
117
+ location: nil,
118
+ comment: comments[node.first_lineno - 1],
119
+ annotations: []
120
+ )
121
+ end
122
+ end
123
+ when :attr_internal_accessor, :attr_internal
124
+ args.each do |arg|
125
+ if arg && (name = literal_to_symbol(arg))
126
+ decls << RBS::AST::Members::AttrAccessor.new(
127
+ name: name,
128
+ ivar_name: :"@_#{name}",
129
+ type: RBS::Types::Bases::Any.new(location: nil),
130
+ kind: context.attribute_kind,
131
+ location: nil,
132
+ comment: comments[node.first_lineno - 1],
133
+ annotations: []
134
+ )
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
140
+
88
141
  def class_new_method_to_type(node)
89
142
  case node.type
90
143
  when :CALL
@@ -122,14 +175,14 @@ using Module.new {
122
175
 
123
176
  def struct_as_superclass
124
177
  name = RBS::TypeName.new(name: 'Struct', namespace: RBS::Namespace.root)
125
- RBS::AST::Declarations::Class::Super.new(name: name, args: ['untyped'])
178
+ RBS::AST::Declarations::Class::Super.new(name: name, args: ['untyped'], location: nil)
126
179
  end
127
180
  end
128
181
  }
129
182
 
130
183
  module PrototypeExt
131
184
  def process(...)
132
- process_class_methods(...) || process_struct_new(...) || super
185
+ process_class_methods(...) || process_struct_new(...) || process_attr_internal(...) || super
133
186
  end
134
187
 
135
188
  def literal_to_type(node)