rbs_active_hash 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 29417b6830a461114cf3825a04a76747c16e936a6b3bc6a1e7385393dd26333c
4
- data.tar.gz: 8382e0a1f22ff0d6e653bfe2d095d437551768d379e82680ddc142ca4c8d6554
3
+ metadata.gz: f12b41b5d7f8ba64d20e27c4f7f21e677cd0ee2fa8f08db13ec5daef40c9b55a
4
+ data.tar.gz: 1a21add9c8606ac60158813d275a2e702353e7d70b61019228f1b1ed152d81f9
5
5
  SHA512:
6
- metadata.gz: aa87db3f4f6c2cf132f9be5697ad69feeb7fbc2a380eb864ed6f32a3748eaef7803433e00e4abccbd0ca4499caf09b07c29e90b70760a98d8117a36b6648ce7c
7
- data.tar.gz: 9d2a71a1429971f679160fab88f61aa2ec38a2553c397163448c60c6685955c5dff77da19f7acb10866b5f22ee097f93c9bfd51a77e4d714e947a20271e8ab57
6
+ metadata.gz: 6727269c9ffe5664c7c6a342eeafb0f715ea177929e8e82c5d76ea86593c3124e07074d987ea4755fc47d041319ef81892df9a71bf16b1af505edd42357b9602
7
+ data.tar.gz: c9e7452a80261991c3d7684c41c3dc906a7b83943fa5f2189f0af9b48bd420465aa0ab7d4bbdd89fc5225605a67ec5342341796ee1b3c6b860d87e55a53b2d1d
data/.rubocop.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  AllCops:
2
- TargetRubyVersion: 3.0
2
+ TargetRubyVersion: 2.7
3
3
 
4
4
  Style/Documentation:
5
5
  Enabled: false
data/Gemfile CHANGED
@@ -7,7 +7,11 @@ gemspec
7
7
 
8
8
  gem "rake", "~> 13.0"
9
9
 
10
- gem "rubocop", "~> 1.54"
10
+ gem "rubocop", "~> 1.55"
11
+
12
+ group :test do
13
+ gem "activerecord"
14
+ end
11
15
 
12
16
  group :development do
13
17
  gem "rspec", require: false
@@ -18,6 +22,5 @@ end
18
22
 
19
23
  # dependencies only for signature
20
24
  group :signature do
21
- gem "activerecord"
22
25
  gem "railties"
23
26
  end
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rbs_active_hash (1.1.0)
4
+ rbs_active_hash (1.2.0)
5
5
  active_hash
6
6
  rbs
7
7
  rbs_rails
@@ -56,7 +56,7 @@ GEM
56
56
  crass (~> 1.0.2)
57
57
  nokogiri (>= 1.12.0)
58
58
  method_source (1.0.0)
59
- minitest (5.18.1)
59
+ minitest (5.19.0)
60
60
  nokogiri (1.15.2-x86_64-darwin)
61
61
  racc (~> 1.4)
62
62
  nokogiri (1.15.2-x86_64-linux)
@@ -91,12 +91,12 @@ GEM
91
91
  rb-fsevent (0.11.2)
92
92
  rb-inotify (0.10.1)
93
93
  ffi (~> 1.0)
94
- rbs (3.1.1)
94
+ rbs (3.1.3)
95
95
  rbs_rails (0.12.0)
96
96
  parser
97
97
  rbs (>= 1)
98
98
  regexp_parser (2.8.1)
99
- rexml (3.2.5)
99
+ rexml (3.2.6)
100
100
  rspec (3.12.0)
101
101
  rspec-core (~> 3.12.0)
102
102
  rspec-expectations (~> 3.12.0)
@@ -113,7 +113,7 @@ GEM
113
113
  diff-lcs (>= 1.2.0, < 2.0)
114
114
  rspec-support (~> 3.12.0)
115
115
  rspec-support (3.12.0)
116
- rubocop (1.54.2)
116
+ rubocop (1.55.1)
117
117
  json (~> 2.3)
118
118
  language_server-protocol (>= 3.17.0)
119
119
  parallel (~> 1.10)
@@ -121,14 +121,14 @@ GEM
121
121
  rainbow (>= 2.2.2, < 4.0)
122
122
  regexp_parser (>= 1.8, < 3.0)
123
123
  rexml (>= 3.2.5, < 4.0)
124
- rubocop-ast (>= 1.28.0, < 2.0)
124
+ rubocop-ast (>= 1.28.1, < 2.0)
125
125
  ruby-progressbar (~> 1.7)
126
126
  unicode-display_width (>= 2.4.0, < 3.0)
127
127
  rubocop-ast (1.29.0)
128
128
  parser (>= 3.2.1.0)
129
129
  ruby-progressbar (1.13.0)
130
130
  securerandom (0.2.2)
131
- steep (1.5.1)
131
+ steep (1.5.2)
132
132
  activesupport (>= 5.1)
133
133
  concurrent-ruby (>= 1.1.10)
134
134
  csv (>= 3.0.9)
@@ -153,6 +153,7 @@ GEM
153
153
  zeitwerk (2.6.8)
154
154
 
155
155
  PLATFORMS
156
+ x86_64-darwin-19
156
157
  x86_64-darwin-21
157
158
  x86_64-linux
158
159
 
@@ -163,8 +164,8 @@ DEPENDENCIES
163
164
  rbs_active_hash!
164
165
  rspec
165
166
  rspec-daemon
166
- rubocop (~> 1.54)
167
+ rubocop (~> 1.55)
167
168
  steep
168
169
 
169
170
  BUNDLED WITH
170
- 2.4.13
171
+ 2.4.4
@@ -40,6 +40,7 @@ module RbsActiveHash
40
40
  <<~RBS
41
41
  #{header}
42
42
  #{enum_decls}
43
+ #{association_decls}
43
44
  #{method_decls}
44
45
  #{footer}
45
46
  RBS
@@ -97,6 +98,64 @@ module RbsActiveHash
97
98
  end
98
99
  end
99
100
 
101
+ def association_decls # rubocop:disable Metrics/AbcSize
102
+ return unless klass.ancestors.include? ::ActiveHash::Associations
103
+
104
+ path, = Object.const_source_location(klass_name)
105
+ return unless path
106
+
107
+ parser = Associations::Parser.new
108
+ parser.parse(IO.read(path.to_s), klass_name.split("::").map(&:to_sym))
109
+
110
+ <<~RBS
111
+ include ActiveHash::Associations
112
+ extend ActiveHash::Associations::Methods
113
+
114
+ #{has_many_decls(parser.has_many)}
115
+ #{has_one_decls(parser.has_one)}
116
+ #{belongs_to_decls(parser.belongs_to)}
117
+ RBS
118
+ end
119
+
120
+ def has_many_decls(definitions) # rubocop:disable Naming/PredicateName
121
+ definitions.map do |definition|
122
+ association_id, options = definition
123
+ klass = options.fetch(:class_name, association_id.to_s.classify).constantize
124
+
125
+ relation = if Object.const_defined?(:ActiveRecord) && klass.ancestors.include?(ActiveRecord::Base)
126
+ "#{klass.name}::ActiveRecord_Relation"
127
+ else
128
+ "Array[#{klass.name}]"
129
+ end
130
+
131
+ <<~RBS
132
+ def #{association_id}: () -> #{relation}
133
+ def #{association_id.to_s.underscore.singularize}_ids: () -> Array[Integer]
134
+ RBS
135
+ end.join("\n")
136
+ end
137
+
138
+ def has_one_decls(definitions) # rubocop:disable Naming/PredicateName
139
+ definitions.map do |definition|
140
+ association_id, options = definition
141
+ class_name = options.fetch(:class_name, association_id.to_s.classify).constantize
142
+
143
+ "def #{association_id}: () -> #{class_name}"
144
+ end.join("\n")
145
+ end
146
+
147
+ def belongs_to_decls(definitions)
148
+ definitions.map do |definition|
149
+ association_id, options = definition
150
+ class_name = options.fetch(:class_name, association_id.to_s.classify).constantize
151
+
152
+ <<~RBS
153
+ def #{association_id}: () -> #{class_name}
154
+ def #{association_id}=: (Integer) -> Integer
155
+ RBS
156
+ end.join("\n")
157
+ end
158
+
100
159
  def method_decls
101
160
  method_names.map do |method|
102
161
  method_type = stringify_type(method_types.fetch(method, "untyped"))
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rbs"
4
+
5
+ module RbsActiveHash
6
+ module Associations
7
+ class AssociationDefinition < RBS::AST::Members::Include
8
+ end
9
+
10
+ class RB < RBS::Prototype::RB
11
+ def process(node, decls:, comments:, context:)
12
+ case node.type
13
+ when :FCALL, :VCALL
14
+ case node.children.first
15
+ when :has_many, :has_one, :belongs_to
16
+ decls << AssociationDefinition.new(
17
+ name: RBS::TypeName.new(name: node.children.first, namespace: RBS::Namespace.root),
18
+ args: node.children[1],
19
+ annotations: [],
20
+ location: nil,
21
+ comment: nil
22
+ )
23
+ else
24
+ super
25
+ end
26
+ else
27
+ super
28
+ end
29
+ end
30
+ end
31
+
32
+ class Parser
33
+ attr_reader :has_many, :has_one, :belongs_to
34
+
35
+ def initialize
36
+ @has_many = []
37
+ @has_one = []
38
+ @belongs_to = []
39
+ end
40
+
41
+ def parse(string, target)
42
+ parser = RB.new
43
+ parser.parse(string)
44
+ parser.decls.each do |decl|
45
+ process(decl, target)
46
+ end
47
+ end
48
+
49
+ def process(node, target)
50
+ case node
51
+ when RBS::AST::Declarations::Module, RBS::AST::Declarations::Class
52
+ name = node.name.split
53
+ if target[...name.size] == name
54
+ node.members.each do |member|
55
+ process(member, target[name.size...].to_a)
56
+ end
57
+ end
58
+ when AssociationDefinition
59
+ process_association_definition(node) if target.empty?
60
+ end
61
+ end
62
+
63
+ def process_association_definition(node)
64
+ case node.name.name
65
+ when :has_many
66
+ association_id, args = node_to_literal(node.args)
67
+ @has_many << [association_id, args.to_h]
68
+ when :has_one
69
+ association_id, args = node_to_literal(node.args)
70
+ @has_one << [association_id, args.to_h]
71
+ when :belongs_to
72
+ association_id, args = node_to_literal(node.args)
73
+ @belongs_to << [association_id, args.to_h]
74
+ end
75
+ end
76
+
77
+ def node_to_literal(node)
78
+ case node.type
79
+ when :LIST
80
+ node.children[...-1].map { |child| node_to_literal(child) }
81
+ when :LIT, :STR
82
+ node.children.first
83
+ when :HASH
84
+ Hash[*node_to_literal(node.children.first)]
85
+ else
86
+ node
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RbsActiveHash
4
- VERSION = "1.1.0"
4
+ VERSION = "1.2.0"
5
5
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "rbs_active_hash/active_hash"
4
+ require_relative "rbs_active_hash/associations"
4
5
  require_relative "rbs_active_hash/version"
5
6
 
6
7
  module RbsActiveHash
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
12
12
  spec.description = "A RBS files generator for ActiveHash models"
13
13
  spec.homepage = "https://github.com/tk0miya/rbs_active_hash"
14
14
  spec.license = "MIT"
15
- spec.required_ruby_version = ">= 3.0"
15
+ spec.required_ruby_version = ">= 2.7"
16
16
 
17
17
  spec.metadata["homepage_uri"] = spec.homepage
18
18
  spec.metadata["source_code_uri"] = spec.homepage
@@ -2,7 +2,7 @@
2
2
  sources:
3
3
  - type: git
4
4
  name: ruby/gem_rbs_collection
5
- revision: aeede7258d020bfd509541e0c8075ce833292409
5
+ revision: 965029a810c265f39b2b85f8c0edc160e5275e3d
6
6
  remote: https://github.com/ruby/gem_rbs_collection.git
7
7
  repo_dir: gems
8
8
  path: ".gem_rbs_collection"
@@ -16,7 +16,7 @@ gems:
16
16
  source:
17
17
  type: git
18
18
  name: ruby/gem_rbs_collection
19
- revision: 280d44d7671abfa909f2966fbef94bca5be082de
19
+ revision: 965029a810c265f39b2b85f8c0edc160e5275e3d
20
20
  remote: https://github.com/ruby/gem_rbs_collection.git
21
21
  repo_dir: gems
22
22
  - name: actionview
@@ -24,7 +24,7 @@ gems:
24
24
  source:
25
25
  type: git
26
26
  name: ruby/gem_rbs_collection
27
- revision: 280d44d7671abfa909f2966fbef94bca5be082de
27
+ revision: 965029a810c265f39b2b85f8c0edc160e5275e3d
28
28
  remote: https://github.com/ruby/gem_rbs_collection.git
29
29
  repo_dir: gems
30
30
  - name: active_hash
@@ -32,7 +32,7 @@ gems:
32
32
  source:
33
33
  type: git
34
34
  name: ruby/gem_rbs_collection
35
- revision: 280d44d7671abfa909f2966fbef94bca5be082de
35
+ revision: 965029a810c265f39b2b85f8c0edc160e5275e3d
36
36
  remote: https://github.com/ruby/gem_rbs_collection.git
37
37
  repo_dir: gems
38
38
  - name: activemodel
@@ -40,7 +40,7 @@ gems:
40
40
  source:
41
41
  type: git
42
42
  name: ruby/gem_rbs_collection
43
- revision: 280d44d7671abfa909f2966fbef94bca5be082de
43
+ revision: 965029a810c265f39b2b85f8c0edc160e5275e3d
44
44
  remote: https://github.com/ruby/gem_rbs_collection.git
45
45
  repo_dir: gems
46
46
  - name: activerecord
@@ -48,7 +48,7 @@ gems:
48
48
  source:
49
49
  type: git
50
50
  name: ruby/gem_rbs_collection
51
- revision: 280d44d7671abfa909f2966fbef94bca5be082de
51
+ revision: 965029a810c265f39b2b85f8c0edc160e5275e3d
52
52
  remote: https://github.com/ruby/gem_rbs_collection.git
53
53
  repo_dir: gems
54
54
  - name: activesupport
@@ -56,7 +56,7 @@ gems:
56
56
  source:
57
57
  type: git
58
58
  name: ruby/gem_rbs_collection
59
- revision: 28208148c7e64a25e9b86b9723b4c3a2cef14e81
59
+ revision: 965029a810c265f39b2b85f8c0edc160e5275e3d
60
60
  remote: https://github.com/ruby/gem_rbs_collection.git
61
61
  repo_dir: gems
62
62
  - name: ast
@@ -64,7 +64,7 @@ gems:
64
64
  source:
65
65
  type: git
66
66
  name: ruby/gem_rbs_collection
67
- revision: 28208148c7e64a25e9b86b9723b4c3a2cef14e81
67
+ revision: 965029a810c265f39b2b85f8c0edc160e5275e3d
68
68
  remote: https://github.com/ruby/gem_rbs_collection.git
69
69
  repo_dir: gems
70
70
  - name: cgi
@@ -76,7 +76,7 @@ gems:
76
76
  source:
77
77
  type: git
78
78
  name: ruby/gem_rbs_collection
79
- revision: 28208148c7e64a25e9b86b9723b4c3a2cef14e81
79
+ revision: 965029a810c265f39b2b85f8c0edc160e5275e3d
80
80
  remote: https://github.com/ruby/gem_rbs_collection.git
81
81
  repo_dir: gems
82
82
  - name: date
@@ -88,7 +88,7 @@ gems:
88
88
  source:
89
89
  type: git
90
90
  name: ruby/gem_rbs_collection
91
- revision: 28208148c7e64a25e9b86b9723b4c3a2cef14e81
91
+ revision: 965029a810c265f39b2b85f8c0edc160e5275e3d
92
92
  remote: https://github.com/ruby/gem_rbs_collection.git
93
93
  repo_dir: gems
94
94
  - name: json
@@ -116,7 +116,7 @@ gems:
116
116
  source:
117
117
  type: git
118
118
  name: ruby/gem_rbs_collection
119
- revision: 280d44d7671abfa909f2966fbef94bca5be082de
119
+ revision: 965029a810c265f39b2b85f8c0edc160e5275e3d
120
120
  remote: https://github.com/ruby/gem_rbs_collection.git
121
121
  repo_dir: gems
122
122
  - name: optparse
@@ -128,7 +128,7 @@ gems:
128
128
  source:
129
129
  type: git
130
130
  name: ruby/gem_rbs_collection
131
- revision: 28208148c7e64a25e9b86b9723b4c3a2cef14e81
131
+ revision: 965029a810c265f39b2b85f8c0edc160e5275e3d
132
132
  remote: https://github.com/ruby/gem_rbs_collection.git
133
133
  repo_dir: gems
134
134
  - name: pathname
@@ -140,7 +140,7 @@ gems:
140
140
  source:
141
141
  type: git
142
142
  name: ruby/gem_rbs_collection
143
- revision: 280d44d7671abfa909f2966fbef94bca5be082de
143
+ revision: 965029a810c265f39b2b85f8c0edc160e5275e3d
144
144
  remote: https://github.com/ruby/gem_rbs_collection.git
145
145
  repo_dir: gems
146
146
  - name: rails-dom-testing
@@ -148,7 +148,7 @@ gems:
148
148
  source:
149
149
  type: git
150
150
  name: ruby/gem_rbs_collection
151
- revision: 280d44d7671abfa909f2966fbef94bca5be082de
151
+ revision: 965029a810c265f39b2b85f8c0edc160e5275e3d
152
152
  remote: https://github.com/ruby/gem_rbs_collection.git
153
153
  repo_dir: gems
154
154
  - name: railties
@@ -156,7 +156,7 @@ gems:
156
156
  source:
157
157
  type: git
158
158
  name: ruby/gem_rbs_collection
159
- revision: 280d44d7671abfa909f2966fbef94bca5be082de
159
+ revision: 965029a810c265f39b2b85f8c0edc160e5275e3d
160
160
  remote: https://github.com/ruby/gem_rbs_collection.git
161
161
  repo_dir: gems
162
162
  - name: rainbow
@@ -164,11 +164,11 @@ gems:
164
164
  source:
165
165
  type: git
166
166
  name: ruby/gem_rbs_collection
167
- revision: 28208148c7e64a25e9b86b9723b4c3a2cef14e81
167
+ revision: 965029a810c265f39b2b85f8c0edc160e5275e3d
168
168
  remote: https://github.com/ruby/gem_rbs_collection.git
169
169
  repo_dir: gems
170
170
  - name: rbs
171
- version: 3.1.1
171
+ version: 3.1.3
172
172
  source:
173
173
  type: rubygems
174
174
  - name: rbs_rails
@@ -179,6 +179,10 @@ gems:
179
179
  version: '0'
180
180
  source:
181
181
  type: stdlib
182
+ - name: securerandom
183
+ version: '0'
184
+ source:
185
+ type: stdlib
182
186
  - name: singleton
183
187
  version: '0'
184
188
  source:
@@ -16,6 +16,10 @@ module RbsActiveHash
16
16
  def header: () -> String
17
17
  def enum_decls: () -> String?
18
18
  def constants: () -> Array[String]
19
+ def association_decls: () -> String?
20
+ def has_many_decls: (Array[[Symbol, Hash[untyped, untyped]]]) -> String
21
+ def has_one_decls: (Array[[Symbol, Hash[untyped, untyped]]]) -> String
22
+ def belongs_to_decls: (Array[[Symbol, Hash[untyped, untyped]]]) -> String
19
23
  def method_decls: () -> String
20
24
  def method_names: () -> Array[Symbol]
21
25
  def method_types: () -> Hash[Symbol, untyped]
@@ -0,0 +1,21 @@
1
+ module RbsActiveHash
2
+ module Associations
3
+ class AssociationDefinition < RBS::AST::Members::Include
4
+ end
5
+
6
+ class RB < RBS::Prototype::RB
7
+ end
8
+
9
+ class Parser
10
+ attr_reader has_many: Array[[Symbol, Hash[untyped, untyped]]]
11
+ attr_reader has_one: Array[[Symbol, Hash[untyped, untyped]]]
12
+ attr_reader belongs_to: Array[[Symbol, Hash[untyped, untyped]]]
13
+
14
+ def initialize: () -> void
15
+ def parse: (String string, Array[Symbol] target) -> void
16
+ def process: (RBS::AST::Declarations::t | RBS::AST::Members::t node, Array[Symbol] target) -> void
17
+ def process_association_definition: (AssociationDefinition node) -> void
18
+ def node_to_literal: (untyped node) -> untyped
19
+ end
20
+ end
21
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbs_active_hash
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Takeshi KOMIYA
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-07-25 00:00:00.000000000 Z
11
+ date: 2023-08-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: active_hash
@@ -72,6 +72,7 @@ files:
72
72
  - lib/generators/rbs_active_hash/install_generator.rb
73
73
  - lib/rbs_active_hash.rb
74
74
  - lib/rbs_active_hash/active_hash.rb
75
+ - lib/rbs_active_hash/associations.rb
75
76
  - lib/rbs_active_hash/rake_task.rb
76
77
  - lib/rbs_active_hash/version.rb
77
78
  - rbs_active_hash.gemspec
@@ -80,6 +81,7 @@ files:
80
81
  - sig/generators/rbs_active_hash/install_generator.rbs
81
82
  - sig/rbs_active_hash.rbs
82
83
  - sig/rbs_active_hash/active_hash.rbs
84
+ - sig/rbs_active_hash/associations.rbs
83
85
  - sig/rbs_active_hash/rake_task.rbs
84
86
  - sig/shims/rake.rbs
85
87
  - sig/shims/thor.rbs
@@ -98,7 +100,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
98
100
  requirements:
99
101
  - - ">="
100
102
  - !ruby/object:Gem::Version
101
- version: '3.0'
103
+ version: '2.7'
102
104
  required_rubygems_version: !ruby/object:Gem::Requirement
103
105
  requirements:
104
106
  - - ">="