rbs-siggen 0.1.0 → 0.2.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/Rakefile +9 -0
- data/Steepfile +1 -0
- data/exe/rbs-siggen +44 -7
- data/lib/rbs/siggen/version.rb +1 -1
- data/lib/rbs/siggen.rb +209 -40
- data/sig/generated/rbs/siggen/version.rbs +7 -0
- data/sig/generated/rbs/siggen.rbs +30 -6
- data/siggen/activerecord_model.rbs +116 -0
- data/siggen/activerecord_model.rbs.erb +53 -0
- metadata +18 -2
- data/sig/rbs/siggen.rbs +0 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c368db792e08e8417cfc36a43cac9aa49e33eeeaf60c39cc7700db494832553b
|
|
4
|
+
data.tar.gz: 11ac12278d9d200e6258fb7230623213e3342006d138127b17f5fd24a454919d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d0ece64d8a739c938ad31197082f29fb7db72141a3932512117ea8e42073c56002b6db12fc4fdd130e25bc1d4c78178b1a39345299726344bebdab59a8059ed0
|
|
7
|
+
data.tar.gz: aec7870eb75d4fb9d568a546218d4807e1190ac9521b7e50392e0aac4089f79abc5bf6303c621cfddb6f54f44883ba6b0f0e4683a4855308b46147091173eb5c
|
data/Rakefile
CHANGED
|
@@ -16,3 +16,12 @@ Steep::RakeTask.new do |t|
|
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
task default: %i[test rubocop steep]
|
|
19
|
+
|
|
20
|
+
desc "Generate siggen/*.rbs"
|
|
21
|
+
task :run_erb do
|
|
22
|
+
infile = "siggen/activerecord_model.rbs.erb"
|
|
23
|
+
outfile = "siggen/activerecord_model.rbs"
|
|
24
|
+
sh %|ruby -rerb -e 'ERB.new(File.read("#{infile}"), trim_mode: ?-).run' > #{outfile}|
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
task install: :run_erb
|
data/Steepfile
CHANGED
data/exe/rbs-siggen
CHANGED
|
@@ -6,12 +6,16 @@ require "rbs/siggen"
|
|
|
6
6
|
require "pathname"
|
|
7
7
|
require "optparse"
|
|
8
8
|
|
|
9
|
-
options = {
|
|
9
|
+
options = { sig_dirs: [], rails: false }
|
|
10
10
|
parser = OptionParser.new do |opts|
|
|
11
11
|
opts.banner = "Usage: rbs-siggen [options] <lib-path>"
|
|
12
12
|
|
|
13
|
-
opts.on("--sig-dir DIR", "Path to RBS signature directory (
|
|
14
|
-
options[:
|
|
13
|
+
opts.on("--sig-dir DIR", "Path to RBS signature directory (can be specified multiple times)") do |dir|
|
|
14
|
+
options[:sig_dirs] << dir
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
opts.on("--rails", "Preset to generate signatures for Rails applications") do
|
|
18
|
+
options[:rails] = true
|
|
15
19
|
end
|
|
16
20
|
|
|
17
21
|
opts.on("-v", "--version", "Show version") do
|
|
@@ -27,14 +31,47 @@ end
|
|
|
27
31
|
|
|
28
32
|
parser.parse!
|
|
29
33
|
|
|
30
|
-
if ARGV.empty?
|
|
34
|
+
if ARGV.empty? && !options[:rails]
|
|
31
35
|
puts parser
|
|
32
36
|
exit 1
|
|
33
37
|
end
|
|
34
38
|
|
|
39
|
+
options[:sig_dirs] = ["sig"] if options[:sig_dirs].empty?
|
|
40
|
+
|
|
35
41
|
lib_path = ARGV[0]
|
|
36
42
|
|
|
37
|
-
siggen = RBS::Siggen.new
|
|
38
|
-
|
|
39
|
-
|
|
43
|
+
siggen = RBS::Siggen.new do |env_loader|
|
|
44
|
+
options[:sig_dirs].each do |dir|
|
|
45
|
+
env_loader.add path: Pathname(dir)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
Dir.glob("#{Dir.pwd}/**/rbs_collection.yaml").each do |path|
|
|
49
|
+
content = YAML.load_file(path)
|
|
50
|
+
env_loader.add path: Pathname(content["path"]) if Dir.exist?(content["path"])
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
if options[:rails]
|
|
54
|
+
spec = Gem::Specification.find_by_name("rbs-siggen")
|
|
55
|
+
env_loader.add path: Pathname(spec.gem_dir) / "siggen"
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def find_rails_root(start_dir = Dir.pwd)
|
|
60
|
+
Pathname.new(start_dir).ascend do |path|
|
|
61
|
+
return path if File.exist? "#{path}/config/application.rb"
|
|
62
|
+
end
|
|
63
|
+
nil
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
if options[:rails] && lib_path.nil?
|
|
67
|
+
rails_root = find_rails_root
|
|
68
|
+
if rails_root
|
|
69
|
+
siggen.analyze(path: "#{rails_root}/db/schema.rb") do |siggen, _|
|
|
70
|
+
puts siggen.generate
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
else
|
|
74
|
+
siggen.analyze(path: Pathname(lib_path)) do |siggen, _|
|
|
75
|
+
puts siggen.generate
|
|
76
|
+
end
|
|
40
77
|
end
|
data/lib/rbs/siggen/version.rb
CHANGED
data/lib/rbs/siggen.rb
CHANGED
|
@@ -13,11 +13,11 @@ module RBS
|
|
|
13
13
|
# @rbs @typing: untyped
|
|
14
14
|
# @rbs @node: Parser::AST::Node
|
|
15
15
|
|
|
16
|
-
#: (
|
|
17
|
-
def initialize
|
|
16
|
+
#: () ?{ (RBS::EnvironmentLoader) -> void } -> void
|
|
17
|
+
def initialize
|
|
18
18
|
core_root = RBS::EnvironmentLoader::DEFAULT_CORE_ROOT
|
|
19
19
|
env_loader = RBS::EnvironmentLoader.new(core_root: core_root)
|
|
20
|
-
env_loader
|
|
20
|
+
yield env_loader if block_given?
|
|
21
21
|
|
|
22
22
|
env = RBS::Environment.new
|
|
23
23
|
env_loader.load(env: env)
|
|
@@ -33,7 +33,7 @@ module RBS
|
|
|
33
33
|
|
|
34
34
|
#: (path: String) { (Siggen, String) -> void } -> void
|
|
35
35
|
def analyze(path:)
|
|
36
|
-
ruby_files = Dir.glob("#{path}/**/*.rb")
|
|
36
|
+
ruby_files = Dir.glob(path) + Dir.glob("#{path}/**/*.rb")
|
|
37
37
|
ruby_files.each do |file|
|
|
38
38
|
analyze_ruby(File.read(file), name: file)
|
|
39
39
|
yield self, file
|
|
@@ -102,7 +102,7 @@ module RBS
|
|
|
102
102
|
annotations: annotations,
|
|
103
103
|
context: context,
|
|
104
104
|
typing: typing)
|
|
105
|
-
construction.synthesize(source.node)
|
|
105
|
+
construction.synthesize(source.node) unless source.node.nil?
|
|
106
106
|
|
|
107
107
|
@typing = typing
|
|
108
108
|
@node = source.node
|
|
@@ -111,64 +111,233 @@ module RBS
|
|
|
111
111
|
|
|
112
112
|
#: () -> String
|
|
113
113
|
def generate
|
|
114
|
-
|
|
114
|
+
io = ::StringIO.new
|
|
115
|
+
traverse(@node) do |class_name, anno, arg_hash|
|
|
116
|
+
generated = ERB.new(anno).result_with_hash(arg_hash)
|
|
117
|
+
surround_class_def = false
|
|
118
|
+
begin
|
|
119
|
+
::RBS::Parser.parse_signature(generated)
|
|
120
|
+
rescue ::RBS::ParsingError => e
|
|
121
|
+
if e.message =~ /Syntax error: cannot start a declaration/
|
|
122
|
+
surround_class_def = true
|
|
123
|
+
else
|
|
124
|
+
# TODO: Should output human readable error messages
|
|
125
|
+
puts generated # for debug
|
|
126
|
+
raise e
|
|
127
|
+
end
|
|
128
|
+
end
|
|
115
129
|
|
|
116
|
-
|
|
117
|
-
|
|
130
|
+
io.puts "class #{class_name}" if surround_class_def
|
|
131
|
+
io.puts generated
|
|
132
|
+
io.puts "end" if surround_class_def
|
|
133
|
+
end
|
|
134
|
+
io.rewind
|
|
135
|
+
_, _, decls = ::RBS::Parser.parse_signature(io.read || "")
|
|
136
|
+
return "" if decls.empty?
|
|
118
137
|
|
|
119
|
-
|
|
120
|
-
|
|
138
|
+
io = ::StringIO.new
|
|
139
|
+
::RBS::Writer.new(out: io).write(merge_class_declarations(decls))
|
|
140
|
+
io.rewind
|
|
141
|
+
io.readlines.reject { |line| line.strip.empty? }.join
|
|
142
|
+
end
|
|
121
143
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
144
|
+
#: (Parser::AST::Node node, ?Array[untyped] stack) ?{ (String, untyped, Hash[untyped, untyped]) -> void } -> void
|
|
145
|
+
def traverse(node, stack = [], &block)
|
|
146
|
+
return unless node.is_a?(::Parser::AST::Node)
|
|
125
147
|
|
|
126
|
-
|
|
127
|
-
|
|
148
|
+
call_of = begin
|
|
149
|
+
@typing.call_of(node:)
|
|
150
|
+
rescue StandardError
|
|
151
|
+
nil
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
if call_of.nil? ||
|
|
155
|
+
call_of.is_a?(Steep::TypeInference::MethodCall::NoMethodError) || # steep:ignore
|
|
156
|
+
call_of.is_a?(Steep::TypeInference::MethodCall::Untyped) # steep:ignore
|
|
157
|
+
node.children.each do |child|
|
|
158
|
+
traverse(child, stack, &block)
|
|
159
|
+
end
|
|
160
|
+
elsif %i[send block].include?(node.type) # steep:ignore
|
|
161
|
+
call_of.method_decls.each do |method_decl|
|
|
128
162
|
annos = method_decl.method_def
|
|
129
163
|
.member_annotations
|
|
130
164
|
.filter { |a| a.string.include?("siggen:") }
|
|
131
165
|
.map { |a| a.string.split("siggen:")[1].strip }
|
|
132
166
|
next if annos.empty?
|
|
133
167
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
168
|
+
arg_hash = {} #: Hash[untyped, untyped]
|
|
169
|
+
stack.each do |n, c|
|
|
170
|
+
arg_hash.merge!({ c.method_name.to_sym => hash_to_data(create_arg_hash(n, c.method_decls.first)) })
|
|
137
171
|
end
|
|
172
|
+
arg_hash.merge!(create_arg_hash(node, method_decl))
|
|
173
|
+
|
|
174
|
+
annos.each { |anno| yield(create_class_name(method_decl), anno, arg_hash) }
|
|
138
175
|
end
|
|
139
|
-
end
|
|
140
176
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
177
|
+
if node.type == :block
|
|
178
|
+
stack << [node, call_of]
|
|
179
|
+
node.children.each do |child|
|
|
180
|
+
traverse(child, stack, &block)
|
|
181
|
+
end
|
|
182
|
+
stack.pop
|
|
183
|
+
end
|
|
184
|
+
else # rubocop:disable Lint/DuplicateBranch
|
|
185
|
+
node.children.each do |child|
|
|
186
|
+
traverse(child, stack, &block)
|
|
146
187
|
end
|
|
147
|
-
io.puts "end"
|
|
148
188
|
end
|
|
149
|
-
io.rewind
|
|
150
|
-
io.read || ""
|
|
151
189
|
end
|
|
152
190
|
|
|
153
|
-
#: (untyped
|
|
154
|
-
def
|
|
155
|
-
|
|
191
|
+
#: (untyped) -> String
|
|
192
|
+
def create_class_name(method_decl)
|
|
193
|
+
receiver_type = method_decl.method_name.type_name.relative!
|
|
194
|
+
"#{receiver_type.namespace}#{receiver_type.name}"
|
|
195
|
+
end
|
|
156
196
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
197
|
+
#: (Parser::AST::Node, untyped) -> Hash[Symbol, untyped]
|
|
198
|
+
def create_arg_hash(node, method_decl)
|
|
199
|
+
send_node = node.type == :block ? node.children.first : node
|
|
200
|
+
_, _, *args = send_node.children
|
|
201
|
+
args = args.map { |arg_node| arg_node.type == :kwargs ? arg_node.children : arg_node.children[0] }.flatten
|
|
202
|
+
positional_args = args.reject { |arg_node| arg_node.respond_to?(:type) && arg_node.type == :pair }
|
|
203
|
+
keyword_args = args.filter do |arg_node|
|
|
204
|
+
arg_node.respond_to?(:type) && arg_node.type == :pair
|
|
205
|
+
end.to_h do |pair_node| # rubocop:disable Style/MultilineBlockChain
|
|
206
|
+
key = pair_node.children[0].children[0]
|
|
207
|
+
val_node = pair_node.children[1]
|
|
208
|
+
val = val_node.children[0] || val_node
|
|
209
|
+
val = val.type == :true if val.respond_to?(:type) # rubocop:disable Lint/BooleanSymbol
|
|
210
|
+
[key, val]
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
type = method_decl.method_def.type.type
|
|
214
|
+
hash = {} #: Hash[Symbol, untyped]
|
|
215
|
+
hash[:___node] = send_node
|
|
216
|
+
hash[:___source] = commentify(node.location.expression.source, node.location.expression.column)
|
|
217
|
+
hash[:___comment_of] = self
|
|
218
|
+
|
|
219
|
+
type.required_positionals.map(&:name).each do |name|
|
|
220
|
+
hash[name] = positional_args.shift
|
|
221
|
+
end
|
|
222
|
+
type.optional_positionals.map(&:name).each do |name|
|
|
223
|
+
hash[name] = positional_args.shift
|
|
161
224
|
end
|
|
225
|
+
hash[type.rest_positionals.name] = positional_args.dup unless type.rest_positionals.nil?
|
|
162
226
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
yield(node, call_of)
|
|
227
|
+
type.required_keywords.each_key do |name|
|
|
228
|
+
hash[name] = keyword_args[name]
|
|
229
|
+
keyword_args.delete(name)
|
|
167
230
|
end
|
|
231
|
+
type.optional_keywords.each_key do |name|
|
|
232
|
+
hash[name] = keyword_args[name]
|
|
233
|
+
keyword_args.delete(name)
|
|
234
|
+
end
|
|
235
|
+
hash[type.rest_keywords.name] = keyword_args.dup unless type.rest_keywords.nil?
|
|
236
|
+
hash
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
#: (Hash[Symbol, untyped]) -> untyped
|
|
240
|
+
def hash_to_data(hash)
|
|
241
|
+
Data.define(*hash.keys).new(*hash.values)
|
|
242
|
+
end
|
|
168
243
|
|
|
169
|
-
|
|
170
|
-
|
|
244
|
+
#: (Array[untyped]) -> Array[untyped]
|
|
245
|
+
def merge_class_declarations(decls)
|
|
246
|
+
# 同じ名前のClass宣言をグループ化
|
|
247
|
+
grouped = decls.group_by do |decl|
|
|
248
|
+
case decl
|
|
249
|
+
when RBS::AST::Declarations::Class
|
|
250
|
+
[:class,
|
|
251
|
+
decl.name]
|
|
252
|
+
when RBS::AST::Declarations::Module
|
|
253
|
+
[:module,
|
|
254
|
+
decl.name]
|
|
255
|
+
else
|
|
256
|
+
[:other, decl.object_id] # その他はマージしない
|
|
257
|
+
end
|
|
171
258
|
end
|
|
259
|
+
|
|
260
|
+
grouped.map do |(kind, _name), group|
|
|
261
|
+
if kind == :class && group.size > 1
|
|
262
|
+
# 複数のClass宣言をマージ
|
|
263
|
+
primary = group.find(&:super_class) || group.first
|
|
264
|
+
merged_members = merge_class_declarations(group.flat_map(&:members))
|
|
265
|
+
merged_annotations = group.flat_map(&:annotations).uniq
|
|
266
|
+
merged_comment = group.map(&:comment).compact.first
|
|
267
|
+
|
|
268
|
+
RBS::AST::Declarations::Class.new(
|
|
269
|
+
name: primary.name,
|
|
270
|
+
type_params: primary.type_params,
|
|
271
|
+
super_class: primary.super_class,
|
|
272
|
+
members: merged_members,
|
|
273
|
+
annotations: merged_annotations,
|
|
274
|
+
location: primary.location,
|
|
275
|
+
comment: merged_comment
|
|
276
|
+
)
|
|
277
|
+
elsif kind == :module && group.size > 1
|
|
278
|
+
# 複数のModule宣言をマージ
|
|
279
|
+
primary = group.first
|
|
280
|
+
merged_members = merge_class_declarations(group.flat_map(&:members))
|
|
281
|
+
merged_annotations = group.flat_map(&:annotations).uniq
|
|
282
|
+
merged_comment = group.map(&:comment).compact.first
|
|
283
|
+
merged_self_types = group.flat_map(&:self_types).uniq
|
|
284
|
+
|
|
285
|
+
RBS::AST::Declarations::Module.new(
|
|
286
|
+
name: primary.name,
|
|
287
|
+
type_params: primary.type_params,
|
|
288
|
+
self_types: merged_self_types,
|
|
289
|
+
members: merged_members,
|
|
290
|
+
annotations: merged_annotations,
|
|
291
|
+
location: primary.location,
|
|
292
|
+
comment: merged_comment
|
|
293
|
+
)
|
|
294
|
+
else
|
|
295
|
+
group
|
|
296
|
+
end
|
|
297
|
+
end.flatten
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
#: (String) -> Array[untyped]
|
|
301
|
+
def method_definitions(type_with_name)
|
|
302
|
+
definition_builder = RBS::DefinitionBuilder.new(env: @env)
|
|
303
|
+
|
|
304
|
+
definition = if type_with_name.include?("#")
|
|
305
|
+
type, name = type_with_name.split("#")
|
|
306
|
+
return [] if type.nil? || name.nil?
|
|
307
|
+
|
|
308
|
+
type_name = TypeName.parse(type).absolute!
|
|
309
|
+
return [] unless @env.module_name?(type_name)
|
|
310
|
+
|
|
311
|
+
definition_builder.build_instance(type_name)
|
|
312
|
+
else
|
|
313
|
+
type, name = type_with_name.split(".")
|
|
314
|
+
return [] if type.nil? || name.nil?
|
|
315
|
+
|
|
316
|
+
type_name = TypeName.parse(type).absolute!
|
|
317
|
+
return [] unless @env.module_name?(type_name)
|
|
318
|
+
|
|
319
|
+
definition_builder.build_singleton(TypeName.parse(type).absolute!)
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
method = definition.methods[name.to_sym]
|
|
323
|
+
return [] unless method
|
|
324
|
+
|
|
325
|
+
method.defs.map(&:member)
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
#: (String) -> String
|
|
329
|
+
def comment_of(type_with_name)
|
|
330
|
+
method_definitions(type_with_name).map(&:comment).map(&:string).join("\n")
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
#: (String, ?Integer) -> String
|
|
334
|
+
def commentify(string, start_column = 0)
|
|
335
|
+
string.each_line.map { |line| "# #{line.sub(/\A {0,#{start_column}}/, "")}" }.join.chomp.gsub(/\A# /, "")
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
#: (String) -> String
|
|
339
|
+
def [](type_with_name)
|
|
340
|
+
commentify(comment_of(type_with_name))
|
|
172
341
|
end
|
|
173
342
|
end
|
|
174
343
|
end
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
module RBS
|
|
4
4
|
class Siggen
|
|
5
|
-
@
|
|
5
|
+
@node: Parser::AST::Node
|
|
6
6
|
|
|
7
7
|
@typing: untyped
|
|
8
8
|
|
|
9
|
-
@
|
|
9
|
+
@env: RBS::Environment
|
|
10
10
|
|
|
11
|
-
# : (
|
|
12
|
-
def initialize: (
|
|
11
|
+
# : () ?{ (RBS::EnvironmentLoader) -> void } -> void
|
|
12
|
+
def initialize: () ?{ (RBS::EnvironmentLoader) -> void } -> void
|
|
13
13
|
|
|
14
14
|
# : (String sig_string, ?name: String) -> void
|
|
15
15
|
def add_signature: (String sig_string, ?name: String) -> void
|
|
@@ -23,7 +23,31 @@ module RBS
|
|
|
23
23
|
# : () -> String
|
|
24
24
|
def generate: () -> String
|
|
25
25
|
|
|
26
|
-
# : (untyped
|
|
27
|
-
def traverse: (untyped
|
|
26
|
+
# : (Parser::AST::Node node, ?Array[untyped] stack) ?{ (String, untyped, Hash[untyped, untyped]) -> void } -> void
|
|
27
|
+
def traverse: (Parser::AST::Node node, ?Array[untyped] stack) ?{ (String, untyped, Hash[untyped, untyped]) -> void } -> void
|
|
28
|
+
|
|
29
|
+
# : (untyped) -> String
|
|
30
|
+
def create_class_name: (untyped) -> String
|
|
31
|
+
|
|
32
|
+
# : (Parser::AST::Node, untyped) -> Hash[Symbol, untyped]
|
|
33
|
+
def create_arg_hash: (Parser::AST::Node, untyped) -> Hash[Symbol, untyped]
|
|
34
|
+
|
|
35
|
+
# : (Hash[Symbol, untyped]) -> untyped
|
|
36
|
+
def hash_to_data: (Hash[Symbol, untyped]) -> untyped
|
|
37
|
+
|
|
38
|
+
# : (Array[untyped]) -> Array[untyped]
|
|
39
|
+
def merge_class_declarations: (Array[untyped]) -> Array[untyped]
|
|
40
|
+
|
|
41
|
+
# : (String) -> Array[untyped]
|
|
42
|
+
def method_definitions: (String) -> Array[untyped]
|
|
43
|
+
|
|
44
|
+
# : (String) -> String
|
|
45
|
+
def comment_of: (String) -> String
|
|
46
|
+
|
|
47
|
+
# : (String, ?Integer) -> String
|
|
48
|
+
def commentify: (String, ?Integer) -> String
|
|
49
|
+
|
|
50
|
+
# : (String) -> String
|
|
51
|
+
def []: (String) -> String
|
|
28
52
|
end
|
|
29
53
|
end
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
module ActiveRecord
|
|
2
|
+
class Schema
|
|
3
|
+
def self.[]: (untyped version) -> ActiveRecord::Migration::Current
|
|
4
|
+
end
|
|
5
|
+
class Migration
|
|
6
|
+
class Current
|
|
7
|
+
def define: (version: untyped) { () [self: instance] -> void } -> void
|
|
8
|
+
%a{siggen:
|
|
9
|
+
# In schema.rb, this model is declared as:
|
|
10
|
+
#
|
|
11
|
+
# ```ruby
|
|
12
|
+
# <%= ___source %>
|
|
13
|
+
# ```
|
|
14
|
+
class <%= table_name.classify %>
|
|
15
|
+
include GeneratedAttributeMethods
|
|
16
|
+
end
|
|
17
|
+
}
|
|
18
|
+
def create_table: (untyped table_name, **untyped options) { (ActiveRecord::ConnectionAdapters::ColumnMethods t) -> void } -> void
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
module ConnectionAdapters
|
|
22
|
+
module ColumnMethods
|
|
23
|
+
%a{siggen:
|
|
24
|
+
class <%= create_table.table_name.classify %>
|
|
25
|
+
module GeneratedAttributeMethods
|
|
26
|
+
<% names.each do |name| %>
|
|
27
|
+
# In schema.rb, this column is declared as:
|
|
28
|
+
#
|
|
29
|
+
# ```ruby
|
|
30
|
+
# <%= ___source %>
|
|
31
|
+
# ```
|
|
32
|
+
#
|
|
33
|
+
# This method delegates to `ActiveRecord::AttributeMethods::Read` `#_read_attribute`,
|
|
34
|
+
# passing `"<%= name %>"` as the `attr_name` argument.
|
|
35
|
+
#
|
|
36
|
+
# See the documentation comment for the delegated method below:
|
|
37
|
+
#
|
|
38
|
+
# <%= ___comment_of["ActiveRecord::AttributeMethods::Read#read_attribute"] %>
|
|
39
|
+
def <%= name %>: () -> ::String<%= "?" unless options[:null] == false %>
|
|
40
|
+
<% end %>
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
}
|
|
44
|
+
def text: (*Array[untyped] names, **untyped options) -> void
|
|
45
|
+
%a{siggen:
|
|
46
|
+
class <%= create_table.table_name.classify %>
|
|
47
|
+
module GeneratedAttributeMethods
|
|
48
|
+
<% names.each do |name| %>
|
|
49
|
+
# In schema.rb, this column is declared as:
|
|
50
|
+
#
|
|
51
|
+
# ```ruby
|
|
52
|
+
# <%= ___source %>
|
|
53
|
+
# ```
|
|
54
|
+
#
|
|
55
|
+
# This method delegates to `ActiveRecord::AttributeMethods::Read` `#_read_attribute`,
|
|
56
|
+
# passing `"<%= name %>"` as the `attr_name` argument.
|
|
57
|
+
#
|
|
58
|
+
# See the documentation comment for the delegated method below:
|
|
59
|
+
#
|
|
60
|
+
# <%= ___comment_of["ActiveRecord::AttributeMethods::Read#read_attribute"] %>
|
|
61
|
+
def <%= name %>: () -> ::String<%= "?" unless options[:null] == false %>
|
|
62
|
+
<% end %>
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
}
|
|
66
|
+
def string: (*Array[untyped] names, **untyped options) -> void
|
|
67
|
+
%a{siggen:
|
|
68
|
+
class <%= create_table.table_name.classify %>
|
|
69
|
+
module GeneratedAttributeMethods
|
|
70
|
+
<% names.each do |name| %>
|
|
71
|
+
# In schema.rb, this column is declared as:
|
|
72
|
+
#
|
|
73
|
+
# ```ruby
|
|
74
|
+
# <%= ___source %>
|
|
75
|
+
# ```
|
|
76
|
+
#
|
|
77
|
+
# This method delegates to `ActiveRecord::AttributeMethods::Read` `#_read_attribute`,
|
|
78
|
+
# passing `"<%= name %>"` as the `attr_name` argument.
|
|
79
|
+
#
|
|
80
|
+
# See the documentation comment for the delegated method below:
|
|
81
|
+
#
|
|
82
|
+
# <%= ___comment_of["ActiveRecord::AttributeMethods::Read#read_attribute"] %>
|
|
83
|
+
def <%= name %>: () -> ::ActiveSupport::TimeWithZone<%= "?" unless options[:null] == false %>
|
|
84
|
+
<% end %>
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
}
|
|
88
|
+
def datetime: (*Array[untyped] names, **untyped options) -> void
|
|
89
|
+
%a{siggen:
|
|
90
|
+
class <%= create_table.table_name.classify %>
|
|
91
|
+
module GeneratedAttributeMethods
|
|
92
|
+
<% names.each do |name| %>
|
|
93
|
+
# In schema.rb, this column is declared as:
|
|
94
|
+
#
|
|
95
|
+
# ```ruby
|
|
96
|
+
# <%= ___source %>
|
|
97
|
+
# ```
|
|
98
|
+
#
|
|
99
|
+
# This method delegates to `ActiveRecord::AttributeMethods::Read` `#_read_attribute`,
|
|
100
|
+
# passing `"<%= name %>"` as the `attr_name` argument.
|
|
101
|
+
#
|
|
102
|
+
# See the documentation comment for the delegated method below:
|
|
103
|
+
#
|
|
104
|
+
# <%= ___comment_of["ActiveRecord::AttributeMethods::Read#read_attribute"] %>
|
|
105
|
+
def <%= name %>: () -> ::Integer<%= "?" unless options[:null] == false %>
|
|
106
|
+
<% end %>
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
}
|
|
110
|
+
def integer: (*Array[untyped] names, **untyped options) -> void
|
|
111
|
+
end
|
|
112
|
+
class TableDefinition
|
|
113
|
+
include ColumnMethods
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<%# ruby -rerb -e 'ERB.new(File.read("siggen/activerecord_model.rbs.erb"), trim_mode: ?-).run' > siggen/activerecord_model.rbs -%>
|
|
2
|
+
module ActiveRecord
|
|
3
|
+
class Schema
|
|
4
|
+
def self.[]: (untyped version) -> ActiveRecord::Migration::Current
|
|
5
|
+
end
|
|
6
|
+
class Migration
|
|
7
|
+
class Current
|
|
8
|
+
def define: (version: untyped) { () [self: instance] -> void } -> void
|
|
9
|
+
%a{siggen:
|
|
10
|
+
# In schema.rb, this model is declared as:
|
|
11
|
+
#
|
|
12
|
+
# ```ruby
|
|
13
|
+
# <%%= ___source %>
|
|
14
|
+
# ```
|
|
15
|
+
class <%%= table_name.classify %>
|
|
16
|
+
include GeneratedAttributeMethods
|
|
17
|
+
end
|
|
18
|
+
}
|
|
19
|
+
def create_table: (untyped table_name, **untyped options) { (ActiveRecord::ConnectionAdapters::ColumnMethods t) -> void } -> void
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
module ConnectionAdapters
|
|
23
|
+
module ColumnMethods
|
|
24
|
+
<%- { text: "::String", string: "::String", datetime: "::ActiveSupport::TimeWithZone", integer: "::Integer" }.each do |key, type| -%>
|
|
25
|
+
%a{siggen:
|
|
26
|
+
class <%%= create_table.table_name.classify %>
|
|
27
|
+
module GeneratedAttributeMethods
|
|
28
|
+
<%% names.each do |name| %>
|
|
29
|
+
# In schema.rb, this column is declared as:
|
|
30
|
+
#
|
|
31
|
+
# ```ruby
|
|
32
|
+
# <%%= ___source %>
|
|
33
|
+
# ```
|
|
34
|
+
#
|
|
35
|
+
# This method delegates to `ActiveRecord::AttributeMethods::Read` `#_read_attribute`,
|
|
36
|
+
# passing `"<%%= name %>"` as the `attr_name` argument.
|
|
37
|
+
#
|
|
38
|
+
# See the documentation comment for the delegated method below:
|
|
39
|
+
#
|
|
40
|
+
# <%%= ___comment_of["ActiveRecord::AttributeMethods::Read#read_attribute"] %>
|
|
41
|
+
def <%%= name %>: () -> <%= type %><%%= "?" unless options[:null] == false %>
|
|
42
|
+
<%% end %>
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
}
|
|
46
|
+
def <%= key %>: (*Array[untyped] names, **untyped options) -> void
|
|
47
|
+
<%- end -%>
|
|
48
|
+
end
|
|
49
|
+
class TableDefinition
|
|
50
|
+
include ColumnMethods
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rbs-siggen
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Koji NAKAMURA
|
|
@@ -9,6 +9,20 @@ bindir: exe
|
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: activesupport
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0'
|
|
12
26
|
- !ruby/object:Gem::Dependency
|
|
13
27
|
name: rbs
|
|
14
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -55,7 +69,9 @@ files:
|
|
|
55
69
|
- rbs_collection.lock.yaml
|
|
56
70
|
- rbs_collection.yaml
|
|
57
71
|
- sig/generated/rbs/siggen.rbs
|
|
58
|
-
- sig/rbs/siggen.rbs
|
|
72
|
+
- sig/generated/rbs/siggen/version.rbs
|
|
73
|
+
- siggen/activerecord_model.rbs
|
|
74
|
+
- siggen/activerecord_model.rbs.erb
|
|
59
75
|
homepage: https://github.com/kozy4324/rbs-siggen
|
|
60
76
|
licenses:
|
|
61
77
|
- MIT
|