Skip to content

Instantly share code, notes, and snippets.

@pocke
Created February 23, 2020 10:59
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pocke/a3faa4b87416c3d899e626f9197f2174 to your computer and use it in GitHub Desktop.
Save pocke/a3faa4b87416c3d899e626f9197f2174 to your computer and use it in GitHub Desktop.
Steepで解析できる型定義ファイルを生成する 2020-02-23版
namespace :steep do
task gen: %i[base copy ar2rbs path_helper]
task :base do
require 'ruby/signature'
sig_base_path = Rails.root.join('sig/base.rbs')
files = Dir.glob(['app/**/*.rb', 'lib/**/*.rb']).sort
sh 'bundle', 'exec', 'rbs', 'prototype', 'rb', *files, :out => sig_base_path.to_s
# dedupe classes
decls = Ruby::Signature::Parser.parse_signature(sig_base_path.read)
decl_map = {}
decls.each do |decl|
if d = decl_map[decl.name]
# TODO: Is it right for decl is not a class / module?
c = Ruby::Signature::AST::Declarations::Class
m = Ruby::Signature::AST::Declarations::Module
next unless d.is_a?(c) || d.is_a?(m)
next unless decl.is_a?(c) || decl.is_a?(m)
d.members.concat decl.members
if d.is_a?(c) && decl.is_a?(c)
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)
end
else
decl_map[decl.name] = decl
end
end
sig_base_path.open('w') do |f|
Ruby::Signature::Writer.new(out: f).write(decl_map.values)
end
end
task copy: :environment do
require 'rbs_rails'
to = Rails.root.join('sig/rbs_rails/')
to.mkdir unless to.exist?
RbsRails.copy_signatures(to: to)
end
task ar2rbs: :environment do
require 'rbs_rails'
OUT_DIR = Rails.root / 'sig'
OUT_DIR.mkdir unless OUT_DIR.exist?
Rails.application.eager_load!
ActiveRecord::Base.descendants.each do |klass|
next if klass.abstract_class?
next if klass == Apartment::Adapters::AbstractAdapter::SeparateDbConnectionHandler
path = OUT_DIR / "app/models/#{klass.name.underscore}.rbs"
FileUtils.mkdir_p(path.dirname)
sig = RbsRails::ActiveRecord.class_to_rbs(klass, mode: :extension)
path.write sig
end
end
task path_helper: :environment do
require 'rbs_rails'
out_path = Rails.root.join 'sig/path_helpers.rbs'
rbs = RbsRails::PathHelpers.generate
out_path.write "# Do NOT edit this file because it is generated by rbs_rails\n\n" + rbs
end
end
@pocke
Copy link
Author

pocke commented Feb 23, 2020

Requirements

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment