rbs_rails 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ # patches
2
+
3
+ This directory has monkey patches for RBS to make to pass `rbs validate`.
4
+ These patches are unnecessary ideally, but we need them for some reasons, such as RBS's bug.
@@ -0,0 +1,74 @@
1
+
2
+ module AbstractController
3
+ class Base
4
+ # alias bug: https://github.com/ruby/rbs/issues/458
5
+ def send: (String | Symbol name, *untyped args) ?{ (*untyped) -> untyped } -> untyped
6
+
7
+ # bug: rbs prototype rb isn't aware of `class << self` for attr_reader
8
+ # https://github.com/rails/rails/blob/fbe2433be6e052a1acac63c7faf287c52ed3c5ba/actionpack/lib/abstract_controller/base.rb#L34-L35
9
+ def self.abstract: () -> untyped
10
+ end
11
+ end
12
+
13
+ module ActionController
14
+ class Metal
15
+ # alias bug?: https://github.com/ruby/rbs/issues/458
16
+ def status: -> untyped
17
+ end
18
+
19
+ class LiveTestResponse < Live::Response
20
+ # alias bug?: https://github.com/ruby/rbs/issues/458
21
+ def successful?: -> untyped
22
+ def not_found?: -> untyped
23
+ def server_error?: -> untyped
24
+ end
25
+ end
26
+
27
+ module ActionDispatch
28
+ class Response
29
+ # alias bug: https://github.com/ruby/rbs/issues/458
30
+ attr_accessor cache_control: untyped
31
+
32
+ # alias bug: https://github.com/ruby/rbs/issues/458
33
+ def location: () -> untyped
34
+ end
35
+
36
+ class Cookies
37
+ class CookieJar
38
+ # alias bug: https://github.com/ruby/rbs/issues/458
39
+ def to_h: () -> ::Hash[untyped, untyped]
40
+ | [T, U] () { (untyped) -> [T, U] } -> ::Hash[T, U]
41
+ end
42
+ end
43
+
44
+ module Journey
45
+ module Nodes
46
+ class Terminal < Node
47
+ # alias bug: https://github.com/ruby/rbs/issues/458
48
+ def left: () -> untyped
49
+ end
50
+ end
51
+ end
52
+
53
+ module Routing
54
+ class Mapper
55
+ module Resources
56
+ class SingletonResource < Resource
57
+ # alias bug: https://github.com/ruby/rbs/issues/458
58
+ attr_reader path: untyped
59
+ end
60
+ end
61
+ end
62
+
63
+ class OptionRedirect < Redirect
64
+ # alias bug: https://github.com/ruby/rbs/issues/458
65
+ attr_reader block: untyped
66
+ end
67
+
68
+ class RouteSet
69
+ # alias bug: https://github.com/ruby/rbs/issues/458
70
+ def to_s: () -> String
71
+ end
72
+ end
73
+ end
74
+
@@ -0,0 +1,19 @@
1
+
2
+ module ActionView
3
+ class OutputBuffer < ActiveSupport::SafeBuffer
4
+ # alias bug: https://github.com/ruby/rbs/issues/458
5
+ def safe_concat: (untyped value) -> untyped
6
+ end
7
+
8
+ class LookupContext
9
+ class DetailsKey
10
+ # alias bug: https://github.com/ruby/rbs/issues/458
11
+ def equal?: (untyped other) -> bool
12
+ end
13
+ end
14
+
15
+ class Resolver
16
+ # Defined with meta-programming
17
+ def self.caching: () -> untyped
18
+ end
19
+ end
@@ -0,0 +1,11 @@
1
+ module ActiveModel
2
+ module Serialization
3
+ # alias bug: https://github.com/ruby/rbs/issues/458
4
+ def `send`: (String name, *untyped args) ?{ (*untyped) -> untyped } -> untyped
5
+ end
6
+
7
+ module Validations
8
+ # alias bug: https://github.com/ruby/rbs/issues/458
9
+ def `send`: (String name, *untyped args) ?{ (*untyped) -> untyped } -> untyped
10
+ end
11
+ end
@@ -0,0 +1,84 @@
1
+ module ActiveRecord
2
+ class Relation
3
+ # alias bug: https://github.com/ruby/rbs/issues/458
4
+ def lock_value: () -> untyped
5
+ end
6
+
7
+ module QueryMethods
8
+ # It is defined with meta programming
9
+ def extending_values: () -> untyped
10
+ end
11
+
12
+ module ConnectionAdapters
13
+ module PostgreSQL
14
+ module OID
15
+ class Uuid < ActiveModel::Type::Value
16
+ # alias bug: https://github.com/ruby/rbs/issues/458
17
+ def deserialize: (*untyped) -> untyped
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ module ConnectionAdapters
24
+ class PostgreSQLAdapter < AbstractAdapter
25
+ def database_version: (*untyped) -> untyped
26
+ end
27
+ end
28
+
29
+ class Migration
30
+ class CommandRecorder
31
+ # They are defined with meta programming
32
+ def add_reference: (*untyped) -> untyped
33
+ def remove_reference: (*untyped) -> untyped
34
+ def invert_add_reference: (*untyped) -> untyped
35
+ def invert_remove_reference: (*untyped) -> untyped
36
+ end
37
+ end
38
+
39
+ class Result
40
+ # alias bug: https://github.com/ruby/rbs/issues/458
41
+ def map: [U] () { (untyped arg0) -> U } -> ::Array[U]
42
+ | () -> ::Enumerator[untyped, ::Array[untyped]]
43
+ end
44
+ end
45
+
46
+ module Arel
47
+ module Nodes
48
+ class Quoted < Arel::Nodes::Unary
49
+ # alias bug: https://github.com/ruby/rbs/issues/458
50
+ def value: () -> untyped
51
+ end
52
+
53
+ class Equality < Arel::Nodes::Binary
54
+ # alias bug: https://github.com/ruby/rbs/issues/458
55
+ def left: () -> untyped
56
+ # alias bug: https://github.com/ruby/rbs/issues/458
57
+ def right: () -> untyped
58
+ end
59
+
60
+ class TableAlias < Arel::Nodes::Binary
61
+ # alias bug: https://github.com/ruby/rbs/issues/458
62
+ def left: () -> untyped
63
+ # alias bug: https://github.com/ruby/rbs/issues/458
64
+ def right: () -> untyped
65
+ end
66
+
67
+ class UnqualifiedColumn < Arel::Nodes::Unary
68
+ # alias bug: https://github.com/ruby/rbs/issues/458
69
+ def expr: () -> untyped
70
+ # alias bug: https://github.com/ruby/rbs/issues/458
71
+ def expr=: (untyped) -> untyped
72
+ end
73
+
74
+ class ValuesList < Unary
75
+ # alias bug: https://github.com/ruby/rbs/issues/458
76
+ def expr: () -> untyped
77
+ end
78
+
79
+ class With < Arel::Nodes::Unary
80
+ # alias bug: https://github.com/ruby/rbs/issues/458
81
+ def expr: () -> untyped
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,48 @@
1
+ class Object
2
+ # Object#sum is actually not defined, but rbs prototype rb generates it mistakenly due to `class << Benchmark`.
3
+ # So we need to define it to suppress the alias error.
4
+ def sum: () -> untyped
5
+ end
6
+
7
+ class Time
8
+ # alias bug: https://github.com/ruby/rbs/issues/458
9
+ def xmlschema: (?::Integer fraction_digits) -> ::String
10
+ end
11
+
12
+ module ActiveSupport
13
+ class TestCase < ::Minitest::Test
14
+ # alias bug: https://github.com/ruby/rbs/issues/458
15
+ def name: () -> untyped
16
+ def assert_raises: (*untyped) -> untyped
17
+ def refute_empty: (*untyped) -> untyped
18
+ def refute_equal: (*untyped) -> untyped
19
+ def refute_in_delta: (*untyped) -> untyped
20
+ def refute_in_epsilon: (*untyped) -> untyped
21
+ def refute_includes: (*untyped) -> untyped
22
+ def refute_instance_of: (*untyped) -> untyped
23
+ def refute_kind_of: (*untyped) -> untyped
24
+ def refute_match: (*untyped) -> untyped
25
+ def refute_nil: (*untyped) -> untyped
26
+ def refute_operator: (*untyped) -> untyped
27
+ def refute_predicate: (*untyped) -> untyped
28
+ def refute_respond_to: (*untyped) -> untyped
29
+ def refute_same: (*untyped) -> untyped
30
+ end
31
+
32
+ module Notifications
33
+ class Fanout
34
+ module Subscribers
35
+ class AllMessages
36
+ # alias bug: https://github.com/ruby/rbs/issues/458
37
+ def ===: (untyped) -> bool
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ class TimeWithZone
44
+ # alias bug: https://github.com/ruby/rbs/issues/458
45
+ def <: (untyped) -> bool
46
+ def >: (untyped) -> bool
47
+ end
48
+ end
@@ -0,0 +1,30 @@
1
+
2
+ module Rails
3
+ class Application < Engine
4
+ # alias bug: https://github.com/ruby/rbs/issues/458
5
+ def app: () -> untyped
6
+ end
7
+
8
+ class Engine < Railtie
9
+ # bug: rbs prototype rb isn't aware of `class << self` for attr_*
10
+ def self.isolated: () -> untyped
11
+ def self.isolated=: (untyped) -> untyped
12
+
13
+ # alias bug: https://github.com/ruby/rbs/issues/458
14
+ def self.railtie_name: (?untyped? name) -> untyped
15
+ end
16
+
17
+ module Generators
18
+ class PluginGenerator < AppBase
19
+ # alias bug: https://github.com/ruby/rbs/issues/458
20
+ def app_path: () -> untyped
21
+ end
22
+ end
23
+
24
+ module Initializable
25
+ class Collection[T] < Array[T]
26
+ def each: () -> ::Enumerator[T, self]
27
+ | () { (T item) -> void } -> self
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,5 @@
1
+ module PG
2
+ class Connection
3
+ def async_exec: (*untyped) -> untyped
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ module Que
2
+ class Job
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ class QC
2
+ class Queue
3
+ end
4
+ end
@@ -4,6 +4,7 @@ module Rack
4
4
 
5
5
  class Response
6
6
  module Helpers
7
+ def location: () -> untyped
7
8
  end
8
9
  end
9
10
 
@@ -0,0 +1,4 @@
1
+ module Sidekiq
2
+ module Worker
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Sneakers
2
+ module Worker
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module SuckerPunch
2
+ module Job
3
+ end
4
+ end
@@ -1,5 +1,12 @@
1
1
  #!ruby
2
2
 
3
+ require 'bundler/inline'
4
+
5
+ gemfile do
6
+ source 'https://rubygems.org'
7
+ gem 'rbs', '>= 0.16'
8
+ end
9
+
3
10
  require 'rbs'
4
11
 
5
12
  def args(n)
@@ -0,0 +1,195 @@
1
+ # Usage
2
+ #
3
+ # ruby bin/generate_rbs_from_rails_source_code.rb ../../rails/rails actionpack
4
+
5
+ require 'bundler/inline'
6
+
7
+ require 'pathname'
8
+ require 'open3'
9
+
10
+ SIG_DIR = Pathname('assets/sig/generated/')
11
+
12
+ def bin(c)
13
+ Pathname(__dir__).join(c).to_s
14
+ end
15
+
16
+ def sh!(*cmd, **kwargs)
17
+ puts(cmd.join(' '))
18
+ Open3.capture2(*cmd, **kwargs).then do |out, status|
19
+ raise unless status.success?
20
+
21
+ out
22
+ end
23
+ end
24
+
25
+ def patch!(name, rbs)
26
+ case name
27
+ when 'actionpack'
28
+ rbs.gsub!(/( def _reduce_\d+: \(untyped val, untyped _values\) -> )([A-Z]\w*)/) do
29
+ "#{$~[1]}Nodes::#{$~[2]}"
30
+ end || raise('it looks unnecessary.')
31
+
32
+ # XXX: I guess add-type-params.rb resolves this
33
+ rbs.gsub!('-> Parameter', '-> Parameter[untyped]') || raise('it looks unnecessary')
34
+ when 'railties'
35
+ rbs.gsub!(
36
+ 'class NonSymbolAccessDeprecatedHash < HashWithIndifferentAccess',
37
+ 'class NonSymbolAccessDeprecatedHash[T, U] < HashWithIndifferentAccess[T, U]')
38
+ # XXX: I guess add-type-params.rb resolves this
39
+ rbs.gsub!(
40
+ 'def middleware: () -> Hash',
41
+ 'def middleware: () -> Hash[untyped, untyped]')
42
+ # XXX: I guess add-type-params.rb resolves this
43
+ rbs.gsub!(
44
+ 'def +: (untyped other) -> Collection',
45
+ 'def +: (untyped other) -> Collection[untyped]')
46
+ # XXX: I guess add-type-params.rb resolves this
47
+ rbs.gsub!(
48
+ 'def initializers_for: (untyped binding) -> Collection',
49
+ 'def initializers_for: (untyped binding) -> Collection[untyped]')
50
+ when 'activesupport'
51
+ rbs.gsub!(
52
+ /^ include Java$/,
53
+ ' # include Java # Java module is missing')
54
+ # XXX: I guess add-type-params.rb resolves this
55
+ rbs.gsub!(
56
+ 'class Configuration < ActiveSupport::InheritableOptions',
57
+ 'class Configuration[T, U] < ActiveSupport::InheritableOptions[T, U]')
58
+ # XXX: I guess add-type-params.rb resolves this
59
+ rbs.gsub!(
60
+ 'class InheritableOptions < OrderedOptions',
61
+ 'class InheritableOptions[T, U] < OrderedOptions[T, U]')
62
+ rbs.gsub!( # ref: 5c507aaae492ff5b2002fdd3ece2044b283b5d6f
63
+ 'include ActiveSupport::Logger::Severity',
64
+ 'include ::Logger::Severity')
65
+ # XXX: I guess add-type-params.rb resolves this
66
+ rbs.gsub!(
67
+ 'def with_indifferent_access: () -> ActiveSupport::HashWithIndifferentAccess',
68
+ 'def with_indifferent_access: () -> ActiveSupport::HashWithIndifferentAccess[K, V]')
69
+ # XXX: I guess add-type-params.rb resolves this
70
+ rbs.gsub!(
71
+ 'def inquiry: () -> ActiveSupport::ArrayInquirer',
72
+ 'def inquiry: () -> ActiveSupport::ArrayInquirer[Elem]')
73
+
74
+ # These aliases are actually defined, but it causes duplicated method definition
75
+ rbs.gsub!('alias to_s to_formatted_s', '')
76
+ rbs.gsub!('alias + plus_with_duration', '')
77
+ rbs.gsub!('alias - minus_with_duration', '')
78
+ rbs.gsub!('alias - minus_with_coercion', '')
79
+ rbs.gsub!('alias <=> compare_with_coercion', '')
80
+ rbs.gsub!('alias eql? eql_with_coercion', '')
81
+ rbs.gsub!('alias self.at self.at_with_coercion', '')
82
+ rbs.gsub!('alias inspect readable_inspect', '')
83
+ rbs.gsub!('alias default_inspect inspect', '')
84
+
85
+ rbs.gsub!('HashWithIndifferentAccess: untyped', <<~RBS)
86
+ # NOTE: HashWithIndifferentAccess and ActiveSupport::HashWithIndifferentAccess are the same object
87
+ # but RBS doesn't have class alias syntax
88
+ class HashWithIndifferentAccess[T, U] < ActiveSupport::HashWithIndifferentAccess[T, U]
89
+ end
90
+ RBS
91
+ when 'actionview'
92
+ rbs.gsub!(
93
+ 'class CheckBoxBuilder < Builder',
94
+ 'class CheckBoxBuilder < CollectionHelpers::Builder')
95
+ rbs.gsub!(
96
+ 'class RadioButtonBuilder < Builder',
97
+ 'class RadioButtonBuilder < CollectionHelpers::Builder')
98
+ rbs.gsub!('TemplateError: untyped', <<~RBS)
99
+ # It is actual TemplateError = Template::Error, but we can't write it in RBS
100
+ class TemplateError < Template::Error
101
+ end
102
+ RBS
103
+ when 'activerecord'
104
+ rbs.gsub!(':==', 'Symbol') # To avoid syntax error
105
+
106
+ rbs.gsub!(
107
+ '< Type::Value',
108
+ '< ActiveModel::Type::Value')
109
+ rbs.gsub!(
110
+ '< Type::Binary',
111
+ '< ActiveModel::Type::Binary')
112
+ rbs.gsub!(
113
+ '< Type::Decimal',
114
+ '< ActiveModel::Type::Decimal')
115
+ rbs.gsub!(
116
+ '< Type::String',
117
+ '< ActiveModel::Type::String')
118
+ rbs.gsub!(
119
+ '< Type::Integer',
120
+ '< ActiveModel::Type::Integer')
121
+
122
+ rbs.gsub!(
123
+ 'class SchemaDumper < SchemaDumper',
124
+ 'class SchemaDumper < ActiveRecord::SchemaDumper')
125
+ rbs.gsub!(
126
+ 'def schema_creation: () -> SchemaCreation',
127
+ 'def schema_creation: () -> untyped')
128
+ rbs.gsub!('V6_0: untyped', <<~RBS)
129
+ # V6_0 and Current are the same object actually. hack for https://github.com/ruby/rbs/issues/345
130
+ class V6_0 < Current
131
+ end
132
+ RBS
133
+ rbs.gsub!('alias numeric decimal', '')
134
+
135
+ # XXX: I guess add-type-params.rb resolves this
136
+ rbs.gsub!(
137
+ '-> ColumnDefinition',
138
+ '-> ColumnDefinition[untyped]')
139
+ # XXX: I guess add-type-params.rb resolves this
140
+ rbs.gsub!(
141
+ 'def build_point: (untyped x, untyped y) -> ActiveRecord::Point',
142
+ 'def build_point: (untyped x, untyped y) -> ActiveRecord::Point[untyped]')
143
+ # XXX: I guess add-type-params.rb resolves this
144
+ rbs.gsub!(
145
+ 'class NullMigration < MigrationProxy',
146
+ 'class NullMigration[T] < MigrationProxy[T]')
147
+ # XXX: I guess add-type-params.rb resolves this
148
+ rbs.gsub!(
149
+ '-> JoinKeys',
150
+ '-> JoinKeys[untyped]')
151
+ # XXX: I guess add-type-params.rb resolves this
152
+ rbs.gsub!(
153
+ 'def row_num_literal: (untyped order_by) -> RowNumber',
154
+ 'def row_num_literal: (untyped order_by) -> RowNumber[untyped]')
155
+
156
+ rbs.gsub!(
157
+ 'def get_database_version: () -> Version',
158
+ 'def get_database_version: () -> AbstractAdapter::Version')
159
+ rbs.gsub!(
160
+ 'def get_database_version: () -> SQLite3Adapter::Version',
161
+ 'def get_database_version: () -> AbstractAdapter::Version')
162
+ rbs.gsub!(
163
+ 'def []: (untyped name) -> Attribute',
164
+ 'def []: (untyped name) -> ::Arel::Attributes::Attribute')
165
+
166
+ end
167
+ end
168
+
169
+ def generate!(rails_code_dir, name)
170
+ files = Pathname(rails_code_dir).join(name, 'lib').glob('**/*.rb').map(&:to_s)
171
+ generated_rbs_path = SIG_DIR.join("#{name}.rbs")
172
+
173
+ rbs = sh! 'ruby', bin("rbs-prototype-rb.rb"), 'prototype', 'rb', *files
174
+ rbs.gsub!(/^(?<indent>\s*)class (?<name>\S+) < $/) { "#{$~[:indent]}class #{$~[:name]} # Note: It inherits unnamed class, but omitted" }
175
+ rbs.gsub!(/[^[:ascii:]]+/, '(trim non-ascii characters)')
176
+ patch! name, rbs
177
+ generated_rbs_path.write(rbs)
178
+
179
+ rbs = sh! 'ruby', bin('add-type-params.rb'), generated_rbs_path.to_s
180
+ generated_rbs_path.write(rbs)
181
+
182
+ sh!({ 'ONLY' => name }, 'ruby', bin('postprocess.rb'), '-rlogger', '-rmutex_m', '-Iassets/sig', '-Isig', 'assets/')
183
+ end
184
+
185
+ def main(rails_code_dir, name)
186
+ if name == 'all'
187
+ %w[actionpack activejob railties activemodel activesupport actionview activerecord].each do |n|
188
+ generate!(rails_code_dir, n)
189
+ end
190
+ else
191
+ generate!(rails_code_dir, name)
192
+ end
193
+ end
194
+
195
+ main(*ARGV)