rbs_rails 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +8 -0
- data/Gemfile +2 -0
- data/LICENSE +201 -0
- data/README.md +52 -5
- data/Rakefile +6 -1
- data/Steepfile +9 -0
- data/assets/sig/action_controller.rbs +44 -0
- data/assets/sig/action_mailer.rbs +5 -0
- data/assets/sig/action_view.rbs +3 -0
- data/assets/sig/active_record.rbs +4 -0
- data/assets/sig/builtin.rbs +7 -0
- data/assets/sig/generated/activemodel.rbs +3877 -0
- data/assets/sig/generated/activesupport.rbs +11480 -0
- data/assets/sig/libxml.rbs +10 -0
- data/assets/sig/minitest.rbs +2 -0
- data/assets/sig/nokogiri.rbs +8 -0
- data/assets/sig/rails.rbs +11 -0
- data/assets/sig/stdlib.rbs +14 -0
- data/bin/add-type-params.rb +59 -0
- data/bin/merge-duplicate-decls.rb +30 -0
- data/lib/rbs_rails.rb +1 -1
- data/lib/rbs_rails/active_record.rb +14 -3
- data/lib/rbs_rails/path_helpers.rb +1 -0
- data/lib/rbs_rails/version.rb +4 -1
- data/rbs_rails.gemspec +1 -0
- data/sig/fileutils.rbs +3 -0
- data/sig/parser.rbs +14 -0
- data/sig/rbs_rails.rbs +6 -0
- data/sig/rbs_rails/active_record.rbs +59 -0
- data/sig/rbs_rails/path_helpers.rbs +11 -0
- data/sig/rbs_rails/version.rbs +1 -0
- metadata +26 -3
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'rbs'
|
2
|
+
rbs = ARGF.read
|
3
|
+
decls = RBS::Parser.parse_signature(rbs)
|
4
|
+
|
5
|
+
def args(n)
|
6
|
+
(:T..).take(n)
|
7
|
+
end
|
8
|
+
|
9
|
+
def env
|
10
|
+
@env ||= RBS::Environment.new.tap do |env|
|
11
|
+
loader = RBS::EnvironmentLoader.new()
|
12
|
+
loader.load(env: env)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def apply_to_superclass(decl)
|
17
|
+
return unless decl.super_class
|
18
|
+
|
19
|
+
name = decl.super_class.name
|
20
|
+
type = env.find_class(name) || env.find_class(name.absolute!)
|
21
|
+
return unless type
|
22
|
+
return if type.type_params.empty?
|
23
|
+
|
24
|
+
args = args(type.type_params.size)
|
25
|
+
decl.super_class.instance_variable_set(:@args, args)
|
26
|
+
type_params = RBS::AST::Declarations::ModuleTypeParams.new.tap do |tp|
|
27
|
+
args.each do |a|
|
28
|
+
tp.add RBS::AST::Declarations::ModuleTypeParams::TypeParam.new(name: a)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
decl.instance_variable_set(:@type_params, type_params)
|
33
|
+
end
|
34
|
+
|
35
|
+
def apply_to_includes(decl)
|
36
|
+
decl.members.each do |member|
|
37
|
+
next unless member.is_a?(RBS::AST::Members::Mixin)
|
38
|
+
|
39
|
+
name = member.name
|
40
|
+
type = env.find_class(name) || env.find_class(name.absolute!)
|
41
|
+
next unless type
|
42
|
+
next if type.type_params.empty?
|
43
|
+
|
44
|
+
args = type.type_params.size.times.map { :untyped }
|
45
|
+
member.instance_variable_set(:@args, args)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
decls.each do |decl|
|
50
|
+
case decl
|
51
|
+
when RBS::AST::Declarations::Class
|
52
|
+
apply_to_superclass(decl)
|
53
|
+
apply_to_includes(decl)
|
54
|
+
when RBS::AST::Declarations::Module, RBS::AST::Declarations::Interface, RBS::AST::Declarations::Extension
|
55
|
+
apply_to_includes(decl)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
puts RBS::Writer.new(out: $stdout).write(decls)
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'rbs'
|
2
|
+
rbs = ARGF.read
|
3
|
+
|
4
|
+
decls = RBS::Parser.parse_signature(rbs)
|
5
|
+
decl_map = {}
|
6
|
+
decls.each do |decl|
|
7
|
+
if d = decl_map[decl.name]
|
8
|
+
# TODO: Is it right for decl is not a class / module?
|
9
|
+
c = RBS::AST::Declarations::Class
|
10
|
+
m = RBS::AST::Declarations::Module
|
11
|
+
e = RBS::AST::Declarations::Extension
|
12
|
+
raise 'class mismatch' if d.class != decl.class
|
13
|
+
raise 'class mismatch' unless [c,m,e].include?(d.class)
|
14
|
+
|
15
|
+
d.members.concat decl.members
|
16
|
+
d.members.uniq! { if _1.is_a?(RBS::AST::Members::MethodDefinition) then [_1.name, _1.singleton?] else _1 end}
|
17
|
+
case d
|
18
|
+
when c
|
19
|
+
decl_map[decl.name] = c.new(name: d.name, type_params: d.type_params, super_class: d.super_class || decl.super_class, members: d.members, annotations: d.annotations, location: d.location, comment: d.comment)
|
20
|
+
when m
|
21
|
+
decl_map[decl.name] = m.new(name: d.name, type_params: d.type_params, members: d.members, self_type: d.self_type, annotations: d.annotations, location: d.location, comment: d.comment)
|
22
|
+
when e
|
23
|
+
decl_map[decl.name] = e.new(name: d.name, type_params: d.type_params, extension_name: d.extension_name, members: d.members, annotations: d.annotations, location: d.location, comment: d.comment)
|
24
|
+
end
|
25
|
+
else
|
26
|
+
decl_map[decl.name] = decl
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
puts RBS::Writer.new(out: $stdout).write(decl_map.values)
|
data/lib/rbs_rails.rb
CHANGED
@@ -56,7 +56,9 @@ module RbsRails
|
|
56
56
|
when :extension
|
57
57
|
"extension #{klass.name} (RbsRails)"
|
58
58
|
when :class
|
59
|
-
|
59
|
+
# @type var superclass: Class
|
60
|
+
superclass = _ = klass.superclass
|
61
|
+
"class #{klass.name} < #{superclass.name}"
|
60
62
|
else
|
61
63
|
raise "unexpected mode: #{mode}"
|
62
64
|
end
|
@@ -91,6 +93,7 @@ module RbsRails
|
|
91
93
|
end
|
92
94
|
|
93
95
|
private def enum_instance_methods
|
96
|
+
# @type var methods: Array[String]
|
94
97
|
methods = []
|
95
98
|
enum_definitions.each do |hash|
|
96
99
|
hash.each do |name, values|
|
@@ -108,6 +111,7 @@ module RbsRails
|
|
108
111
|
end
|
109
112
|
|
110
113
|
private def enum_scope_methods(singleton:)
|
114
|
+
# @type var methods: Array[String]
|
111
115
|
methods = []
|
112
116
|
enum_definitions.each do |hash|
|
113
117
|
hash.each do |name, values|
|
@@ -191,6 +195,7 @@ module RbsRails
|
|
191
195
|
end
|
192
196
|
|
193
197
|
private def args_to_type(args_node)
|
198
|
+
# @type var res: Array[String]
|
194
199
|
res = []
|
195
200
|
args_node.children.each do |node|
|
196
201
|
case node.type
|
@@ -213,7 +218,9 @@ module RbsRails
|
|
213
218
|
return @parse_model_file if defined?(@parse_model_file)
|
214
219
|
|
215
220
|
|
216
|
-
|
221
|
+
# @type var class_name: String
|
222
|
+
class_name = _ = klass.name
|
223
|
+
path = Rails.root.join('app/models/', class_name.underscore + '.rb')
|
217
224
|
return @parse_model_file = nil unless path.exist?
|
218
225
|
return [] unless path.exist?
|
219
226
|
|
@@ -226,6 +233,7 @@ module RbsRails
|
|
226
233
|
private def traverse(node, &block)
|
227
234
|
return to_enum(__method__, node) unless block_given?
|
228
235
|
|
236
|
+
# @type var block: ^(Parser::AST::Node) -> untyped
|
229
237
|
block.call node
|
230
238
|
node.children.each do |child|
|
231
239
|
traverse(child, &block) if child.is_a?(Parser::AST::Node)
|
@@ -246,7 +254,9 @@ module RbsRails
|
|
246
254
|
case t
|
247
255
|
when :integer
|
248
256
|
Integer.name
|
249
|
-
when :
|
257
|
+
when :float
|
258
|
+
Float.name
|
259
|
+
when :string, :text, :uuid, :binary
|
250
260
|
String.name
|
251
261
|
when :datetime
|
252
262
|
# TODO
|
@@ -266,6 +276,7 @@ module RbsRails
|
|
266
276
|
end
|
267
277
|
|
268
278
|
private
|
279
|
+
# @dynamic klass, mode
|
269
280
|
attr_reader :klass, :mode
|
270
281
|
end
|
271
282
|
end
|
data/lib/rbs_rails/version.rb
CHANGED
data/rbs_rails.gemspec
CHANGED
@@ -9,6 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.summary = %q{A RBS files generator for Rails application}
|
10
10
|
spec.description = %q{A RBS files generator for Rails application}
|
11
11
|
spec.homepage = "https://github.com/pocke/rbs_rails"
|
12
|
+
spec.license = 'Apache-2.0'
|
12
13
|
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
13
14
|
|
14
15
|
spec.metadata["homepage_uri"] = spec.homepage
|
data/sig/fileutils.rbs
ADDED
data/sig/parser.rbs
ADDED
data/sig/rbs_rails.rbs
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
module RbsRails::ActiveRecord
|
2
|
+
def self.class_to_rbs: (untyped klass, mode: untyped mode) -> untyped
|
3
|
+
end
|
4
|
+
|
5
|
+
class RbsRails::ActiveRecord::Generator
|
6
|
+
@parse_model_file: nil | Parser::AST::Node
|
7
|
+
|
8
|
+
def initialize: (singleton(ActiveRecord::Base) klass, mode: (:extension | :class) mode) -> untyped
|
9
|
+
|
10
|
+
def generate: () -> String
|
11
|
+
|
12
|
+
def klass_decl: () -> String
|
13
|
+
|
14
|
+
def relation_decl: () -> String
|
15
|
+
|
16
|
+
def collection_proxy_decl: () -> String
|
17
|
+
|
18
|
+
def header: () -> String
|
19
|
+
|
20
|
+
def associations: () -> String
|
21
|
+
|
22
|
+
def has_many: () -> String
|
23
|
+
|
24
|
+
def has_one: () -> String
|
25
|
+
|
26
|
+
def belongs_to: () -> String
|
27
|
+
|
28
|
+
def enum_instance_methods: () -> String
|
29
|
+
|
30
|
+
def enum_scope_methods: (singleton: untyped `singleton`) -> String
|
31
|
+
|
32
|
+
def enum_definitions: () -> Array[Hash[Symbol, untyped]]
|
33
|
+
|
34
|
+
# We need static analysis to detect enum.
|
35
|
+
# ActiveRecord has `defined_enums` method,
|
36
|
+
# but it does not contain _prefix and _suffix information.
|
37
|
+
def build_enum_definitions: () -> Array[Hash[Symbol, untyped]]
|
38
|
+
|
39
|
+
def enum_method_name: (Hash[Symbol, untyped] hash, Symbol name, Symbol label) -> String
|
40
|
+
|
41
|
+
def scopes: (singleton: untyped `singleton`) -> untyped
|
42
|
+
|
43
|
+
def args_to_type: (untyped args_node) -> untyped
|
44
|
+
|
45
|
+
def parse_model_file: () -> untyped
|
46
|
+
|
47
|
+
def traverse: (Parser::AST::Node node) { (Parser::AST::Node) -> untyped } -> untyped
|
48
|
+
| (Parser::AST::Node node) -> Enumerator[Parser::AST::Node, untyped]
|
49
|
+
|
50
|
+
def relation_class_name: () -> untyped
|
51
|
+
|
52
|
+
def columns: () -> untyped
|
53
|
+
|
54
|
+
def sql_type_to_class: (untyped t) -> untyped
|
55
|
+
|
56
|
+
attr_reader klass: singleton(ActiveRecord::Base)
|
57
|
+
|
58
|
+
attr_reader mode: (:extension | :class)
|
59
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
RbsRails::VERSION: ::String
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbs_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Masataka Pocke Kuwabara
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-06-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|
@@ -32,19 +32,42 @@ extensions: []
|
|
32
32
|
extra_rdoc_files: []
|
33
33
|
files:
|
34
34
|
- ".gitignore"
|
35
|
+
- ".travis.yml"
|
35
36
|
- Gemfile
|
37
|
+
- LICENSE
|
36
38
|
- README.md
|
37
39
|
- Rakefile
|
40
|
+
- Steepfile
|
41
|
+
- assets/sig/action_controller.rbs
|
42
|
+
- assets/sig/action_mailer.rbs
|
43
|
+
- assets/sig/action_view.rbs
|
38
44
|
- assets/sig/active_record.rbs
|
45
|
+
- assets/sig/builtin.rbs
|
46
|
+
- assets/sig/generated/activemodel.rbs
|
47
|
+
- assets/sig/generated/activesupport.rbs
|
48
|
+
- assets/sig/libxml.rbs
|
49
|
+
- assets/sig/minitest.rbs
|
50
|
+
- assets/sig/nokogiri.rbs
|
51
|
+
- assets/sig/rails.rbs
|
52
|
+
- assets/sig/stdlib.rbs
|
53
|
+
- bin/add-type-params.rb
|
39
54
|
- bin/console
|
55
|
+
- bin/merge-duplicate-decls.rb
|
40
56
|
- bin/setup
|
41
57
|
- lib/rbs_rails.rb
|
42
58
|
- lib/rbs_rails/active_record.rb
|
43
59
|
- lib/rbs_rails/path_helpers.rb
|
44
60
|
- lib/rbs_rails/version.rb
|
45
61
|
- rbs_rails.gemspec
|
62
|
+
- sig/fileutils.rbs
|
63
|
+
- sig/parser.rbs
|
64
|
+
- sig/rbs_rails.rbs
|
65
|
+
- sig/rbs_rails/active_record.rbs
|
66
|
+
- sig/rbs_rails/path_helpers.rbs
|
67
|
+
- sig/rbs_rails/version.rbs
|
46
68
|
homepage: https://github.com/pocke/rbs_rails
|
47
|
-
licenses:
|
69
|
+
licenses:
|
70
|
+
- Apache-2.0
|
48
71
|
metadata:
|
49
72
|
homepage_uri: https://github.com/pocke/rbs_rails
|
50
73
|
source_code_uri: https://github.com/pocke/rbs_rails
|