rbs_activerecord 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.claude/hooks/claude-code-web-session-start.sh +14 -0
- data/.claude/hooks/pre-commit-check.sh +73 -0
- data/.claude/hooks/protect-sig-files.sh +45 -0
- data/.claude/hooks/rbs-inline.sh +95 -0
- data/.claude/hooks/self-review.sh +93 -0
- data/.claude/settings.json +58 -0
- data/.rubocop.yml +42 -5
- data/.vscode/settings.json +3 -1
- data/Rakefile +32 -4
- data/lib/generators/rbs_activerecord/install_generator.rb +1 -1
- data/lib/rbs_activerecord/generator/active_storage/instance_methods.rb +2 -1
- data/lib/rbs_activerecord/generator/active_storage/scopes.rb +1 -1
- data/lib/rbs_activerecord/generator/associations.rb +4 -4
- data/lib/rbs_activerecord/generator/attributes.rb +25 -4
- data/lib/rbs_activerecord/generator/delegated_type/instance_methods.rb +5 -5
- data/lib/rbs_activerecord/generator/delegated_type/scopes.rb +3 -3
- data/lib/rbs_activerecord/generator/enum/base.rb +2 -2
- data/lib/rbs_activerecord/generator/enum/instance_methods.rb +3 -3
- data/lib/rbs_activerecord/generator/enum/mappings.rb +2 -2
- data/lib/rbs_activerecord/generator/enum/scopes.rb +2 -2
- data/lib/rbs_activerecord/generator/scopes.rb +2 -2
- data/lib/rbs_activerecord/generator/secure_password.rb +1 -1
- data/lib/rbs_activerecord/generator.rb +1 -1
- data/lib/rbs_activerecord/model.rb +2 -1
- data/lib/rbs_activerecord/parser/evaluator.rb +1 -1
- data/lib/rbs_activerecord/parser/include_expander/module.rb +1 -1
- data/lib/rbs_activerecord/parser/include_expander.rb +4 -4
- data/lib/rbs_activerecord/parser/visitor.rb +1 -1
- data/lib/rbs_activerecord/parser.rb +2 -1
- data/lib/rbs_activerecord/utils.rb +6 -6
- data/lib/rbs_activerecord/version.rb +1 -1
- data/rbs_collection.lock.yaml +131 -63
- data/rbs_collection.yaml +1 -0
- data/sig/generators/rbs_activerecord/install_generator.rbs +1 -1
- data/sig/rbs_activerecord/generator/active_storage/instance_methods.rbs +1 -0
- data/sig/rbs_activerecord/generator/attributes.rbs +10 -0
- data/sig/rbs_activerecord/parser.rbs +2 -1
- data/sig/rbs_activerecord/utils.rbs +2 -2
- metadata +10 -7
|
@@ -19,7 +19,7 @@ module RbsActiverecord
|
|
|
19
19
|
def generate #: String
|
|
20
20
|
<<~RBS.strip
|
|
21
21
|
module GeneratedDelegatedTypeInstanceMethods
|
|
22
|
-
#{delegated_types.map {
|
|
22
|
+
#{delegated_types.map { delegated_type(_1) }.join("\n")}
|
|
23
23
|
end
|
|
24
24
|
RBS
|
|
25
25
|
end
|
|
@@ -27,18 +27,18 @@ module RbsActiverecord
|
|
|
27
27
|
private
|
|
28
28
|
|
|
29
29
|
def delegated_types #: Array[Prism::CallNode]
|
|
30
|
-
declarations.select {
|
|
30
|
+
declarations.select { _1.name == :delegated_type }
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
# @rbs node: Prism::CallNode
|
|
34
|
-
def delegated_type(node) #: String
|
|
34
|
+
def delegated_type(node) #: String
|
|
35
35
|
arguments = node.arguments&.arguments || []
|
|
36
|
-
name, options = arguments.map {
|
|
36
|
+
name, options = arguments.map { Parser.eval_node(_1) } #: [String?, Hash[Symbol, untyped]]
|
|
37
37
|
return "" unless name
|
|
38
38
|
|
|
39
39
|
types = options[:types]
|
|
40
40
|
role_methods = <<~RBS
|
|
41
|
-
def #{name}_class: () -> (#{types.map {
|
|
41
|
+
def #{name}_class: () -> (#{types.map { "::#{_1}" }.join(" | ")})
|
|
42
42
|
def #{name}_name: () -> ::String
|
|
43
43
|
RBS
|
|
44
44
|
|
|
@@ -17,7 +17,7 @@ module RbsActiverecord
|
|
|
17
17
|
def generate #: String
|
|
18
18
|
<<~RBS.strip
|
|
19
19
|
module GeneratedDelegatedTypeScopeMethods[Relation]
|
|
20
|
-
#{delegated_types.map {
|
|
20
|
+
#{delegated_types.map { delegated_type(_1) }.join("\n")}
|
|
21
21
|
end
|
|
22
22
|
RBS
|
|
23
23
|
end
|
|
@@ -25,13 +25,13 @@ module RbsActiverecord
|
|
|
25
25
|
private
|
|
26
26
|
|
|
27
27
|
def delegated_types #: Array[Prism::CallNode]
|
|
28
|
-
declarations.select {
|
|
28
|
+
declarations.select { _1.name == :delegated_type }
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
# @rbs node: Prism::CallNode
|
|
32
32
|
def delegated_type(node) #: String
|
|
33
33
|
arguments = node.arguments&.arguments || []
|
|
34
|
-
name, options = arguments.map {
|
|
34
|
+
name, options = arguments.map { Parser.eval_node(_1) } #: [String?, Hash[Symbol, untyped]]
|
|
35
35
|
return "" unless name
|
|
36
36
|
|
|
37
37
|
options[:types].map do |type|
|
|
@@ -7,9 +7,9 @@ module RbsActiverecord
|
|
|
7
7
|
private
|
|
8
8
|
|
|
9
9
|
# @rbs node: Prism::CallNode
|
|
10
|
-
def parse_arguments(node) #: [String?, Array[String | Symbol], Hash[Symbol, untyped]] # rubocop:disable Metrics/
|
|
10
|
+
def parse_arguments(node) #: [String?, Array[String | Symbol], Hash[Symbol, untyped]] # rubocop:disable Metrics/CyclomaticComplexity
|
|
11
11
|
arguments = node.arguments&.arguments || []
|
|
12
|
-
args = arguments.map {
|
|
12
|
+
args = arguments.map { Parser.eval_node(_1) }
|
|
13
13
|
return nil, [], {} if args.empty?
|
|
14
14
|
|
|
15
15
|
name = args[0] #: String?
|
|
@@ -21,7 +21,7 @@ module RbsActiverecord
|
|
|
21
21
|
def generate #: String
|
|
22
22
|
<<~RBS.strip
|
|
23
23
|
module GeneratedEnumInstanceMethods
|
|
24
|
-
#{enums.map {
|
|
24
|
+
#{enums.map { enum(_1) }.join("\n")}
|
|
25
25
|
end
|
|
26
26
|
RBS
|
|
27
27
|
end
|
|
@@ -29,7 +29,7 @@ module RbsActiverecord
|
|
|
29
29
|
private
|
|
30
30
|
|
|
31
31
|
def enums #: Array[Prism::CallNode]
|
|
32
|
-
declarations.select {
|
|
32
|
+
declarations.select { _1.name == :enum }
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
# @rbs node: Prism::CallNode
|
|
@@ -58,7 +58,7 @@ module RbsActiverecord
|
|
|
58
58
|
|
|
59
59
|
# @rbs name: String
|
|
60
60
|
def column_type(name) #: String
|
|
61
|
-
col = model.columns.find {
|
|
61
|
+
col = model.columns.find { _1.name == name.to_s }
|
|
62
62
|
if col
|
|
63
63
|
sql_type_to_class(col.type)
|
|
64
64
|
else
|
|
@@ -19,7 +19,7 @@ module RbsActiverecord
|
|
|
19
19
|
def generate #: String
|
|
20
20
|
<<~RBS.strip
|
|
21
21
|
module GeneratedEnumMappingMethods
|
|
22
|
-
#{enums.map {
|
|
22
|
+
#{enums.map { enum(_1) }.join("\n")}
|
|
23
23
|
end
|
|
24
24
|
RBS
|
|
25
25
|
end
|
|
@@ -27,7 +27,7 @@ module RbsActiverecord
|
|
|
27
27
|
private
|
|
28
28
|
|
|
29
29
|
def enums #: Array[Prism::CallNode]
|
|
30
|
-
declarations.select {
|
|
30
|
+
declarations.select { _1.name == :enum }
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
# @rbs node: Prism::CallNode
|
|
@@ -19,7 +19,7 @@ module RbsActiverecord
|
|
|
19
19
|
def generate #: String
|
|
20
20
|
<<~RBS.strip
|
|
21
21
|
module GeneratedEnumScopeMethods[Relation]
|
|
22
|
-
#{enums.map {
|
|
22
|
+
#{enums.map { enum(_1) }.join("\n")}
|
|
23
23
|
end
|
|
24
24
|
RBS
|
|
25
25
|
end
|
|
@@ -27,7 +27,7 @@ module RbsActiverecord
|
|
|
27
27
|
private
|
|
28
28
|
|
|
29
29
|
def enums #: Array[Prism::CallNode]
|
|
30
|
-
declarations.select {
|
|
30
|
+
declarations.select { _1.name == :enum }
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
# @rbs node: Prism::CallNode
|
|
@@ -16,7 +16,7 @@ module RbsActiverecord
|
|
|
16
16
|
def generate #: String
|
|
17
17
|
<<~RBS.strip
|
|
18
18
|
module GeneratedScopeMethods[Relation]
|
|
19
|
-
#{scopes.map {
|
|
19
|
+
#{scopes.map { scope(_1) }.join("\n")}
|
|
20
20
|
end
|
|
21
21
|
RBS
|
|
22
22
|
end
|
|
@@ -24,7 +24,7 @@ module RbsActiverecord
|
|
|
24
24
|
private
|
|
25
25
|
|
|
26
26
|
def scopes #: Array[Prism::CallNode]
|
|
27
|
-
declarations.select {
|
|
27
|
+
declarations.select { _1.name == :scope }
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
# @rbs node: Prism::CallNode
|
|
@@ -40,7 +40,7 @@ module RbsActiverecord
|
|
|
40
40
|
return [] unless secure_password?
|
|
41
41
|
|
|
42
42
|
model.klass.instance_methods.grep(/authenticate_/).filter_map do |method|
|
|
43
|
-
next if model.klass.
|
|
43
|
+
next if model.klass.method_defined?(:"#{method}_confirmation")
|
|
44
44
|
|
|
45
45
|
method.to_s.split("_", 2).last
|
|
46
46
|
end
|
|
@@ -14,6 +14,7 @@ module RbsActiverecord
|
|
|
14
14
|
# def columns: () -> Array[untyped]
|
|
15
15
|
# def defined_enums: () -> Hash[String, untyped]
|
|
16
16
|
# def reflect_on_all_associations: (Symbol) -> Array[untyped]
|
|
17
|
+
|
|
17
18
|
def_delegators :klass, :attribute_aliases, :attribute_types, :columns, :defined_enums, :reflect_on_all_associations
|
|
18
19
|
|
|
19
20
|
# @rbs klass: singleton(ActiveRecord::Base)
|
|
@@ -27,7 +28,7 @@ module RbsActiverecord
|
|
|
27
28
|
|
|
28
29
|
def parents #: Array[singleton(ActiveRecord::Base)]
|
|
29
30
|
ancestors = klass.ancestors #: Array[singleton(ActiveRecord::Base)]
|
|
30
|
-
ancestors.select {
|
|
31
|
+
ancestors.select { _1 < ActiveRecord::Base && _1 != klass && !_1.abstract_class? }
|
|
31
32
|
end
|
|
32
33
|
end
|
|
33
34
|
end
|
|
@@ -19,7 +19,7 @@ module RbsActiverecord
|
|
|
19
19
|
when Prism::StringNode
|
|
20
20
|
node.unescaped
|
|
21
21
|
when Prism::ArrayNode
|
|
22
|
-
node.elements.map {
|
|
22
|
+
node.elements.map { eval_node(_1) }
|
|
23
23
|
when Prism::HashNode, Prism::KeywordHashNode
|
|
24
24
|
node.elements.filter_map do |assoc|
|
|
25
25
|
case assoc
|
|
@@ -22,7 +22,7 @@ module RbsActiverecord
|
|
|
22
22
|
def expand #: void
|
|
23
23
|
declarations.each_value do |decls|
|
|
24
24
|
loop do
|
|
25
|
-
index = decls.index {
|
|
25
|
+
index = decls.index { _1.name == :include }
|
|
26
26
|
break unless index
|
|
27
27
|
|
|
28
28
|
included_module = decls.delete_at(index) || raise
|
|
@@ -39,8 +39,8 @@ module RbsActiverecord
|
|
|
39
39
|
# @rbs node: Prism::CallNode
|
|
40
40
|
def included_blocks_for(node) #: Array[Prism::CallNode]
|
|
41
41
|
modules = node.arguments&.arguments.to_a
|
|
42
|
-
.map {
|
|
43
|
-
.
|
|
42
|
+
.map { Parser.eval_node(_1) }
|
|
43
|
+
.grep(String)
|
|
44
44
|
modules.flat_map do |modname|
|
|
45
45
|
mod = const_get(modname)
|
|
46
46
|
next [] unless mod
|
|
@@ -69,7 +69,7 @@ module RbsActiverecord
|
|
|
69
69
|
case node.block.body
|
|
70
70
|
when Prism::StatementsNode
|
|
71
71
|
body = node.block.body.body #: Array[Prism::CallNode]
|
|
72
|
-
body.
|
|
72
|
+
body.grep(Prism::CallNode)
|
|
73
73
|
else
|
|
74
74
|
[]
|
|
75
75
|
end
|
|
@@ -14,8 +14,9 @@ module RbsActiverecord
|
|
|
14
14
|
end
|
|
15
15
|
module_function :parse
|
|
16
16
|
|
|
17
|
+
# @rbs filename: String
|
|
17
18
|
def parse_file(filename) #: Hash[String, Array[Prism::CallNode]]
|
|
18
|
-
File.open(filename) {
|
|
19
|
+
File.open(filename) { parse(_1.read) }
|
|
19
20
|
end
|
|
20
21
|
module_function :parse_file
|
|
21
22
|
|
|
@@ -8,11 +8,11 @@ module RbsActiverecord
|
|
|
8
8
|
def format(str) #: String
|
|
9
9
|
parsed = RBS::Parser.parse_signature(str)
|
|
10
10
|
StringIO.new.tap do |out|
|
|
11
|
-
RBS::Writer.new(out:
|
|
11
|
+
RBS::Writer.new(out:).write(parsed[1] + parsed[2])
|
|
12
12
|
end.string
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
# @rbs
|
|
15
|
+
# @rbs klass: singleton(Object)
|
|
16
16
|
def klass_to_names(klass) #: Array[RBS::TypeName]
|
|
17
17
|
type_name = RBS::TypeName.parse("::#{klass.name}")
|
|
18
18
|
|
|
@@ -26,16 +26,16 @@ module RbsActiverecord
|
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
# @rbs klass: singleton(ActiveRecord::Base)
|
|
29
|
-
def primary_key_type_for(klass) #: String
|
|
29
|
+
def primary_key_type_for(klass) #: String
|
|
30
30
|
case klass.primary_key
|
|
31
31
|
when Array
|
|
32
32
|
primary_keys = klass.primary_key.map(&:to_s)
|
|
33
33
|
types = klass.columns
|
|
34
|
-
.select {
|
|
35
|
-
.map {
|
|
34
|
+
.select { primary_keys.include?(_1.name) }
|
|
35
|
+
.map { sql_type_to_class(_1.type) }
|
|
36
36
|
"[#{types.join(" | ")}]"
|
|
37
37
|
else
|
|
38
|
-
primary_key = klass.columns.find {
|
|
38
|
+
primary_key = klass.columns.find { _1.name == klass.primary_key }
|
|
39
39
|
sql_type_to_class(primary_key.type)
|
|
40
40
|
end
|
|
41
41
|
end
|