lib/tapioca/helpers/rbi_files_helper.rb in tapioca-0.9.2 vs lib/tapioca/helpers/rbi_files_helper.rb in tapioca-0.9.3

- old
+ new

@@ -7,37 +7,37 @@ extend T::Helpers requires_ancestor { Thor::Shell } requires_ancestor { SorbetHelper } + sig { params(index: RBI::Index, dir: String).void } + def index_payload(index, dir) + return unless Dir.exist?(dir) + + say("Loading Sorbet payload... ") + files = Dir.glob("#{dir}/**/*.rbi").sort + parse_and_index_files(index, files) + say(" Done", :green) + end + sig { params(index: RBI::Index, kind: String, file: String).void } def index_rbi(index, kind, file) return unless File.exist?(file) say("Loading #{kind} RBIs from #{file}... ") - time = Benchmark.realtime do - parse_and_index_files(index, [file], number_of_workers: 1) - end - say(" Done ", :green) - say("(#{time.round(2)}s)") + parse_and_index_file(index, file) + say(" Done", :green) end - sig { params(index: RBI::Index, kind: String, dir: String, number_of_workers: T.nilable(Integer)).void } - def index_rbis(index, kind, dir, number_of_workers:) + sig { params(index: RBI::Index, kind: String, dir: String).void } + def index_rbis(index, kind, dir) return unless Dir.exist?(dir) && !Dir.empty?(dir) - if kind == "payload" - say("Loading Sorbet payload... ") - else - say("Loading #{kind} RBIs from #{dir}... ") - end - time = Benchmark.realtime do - files = Dir.glob("#{dir}/**/*.rbi").sort - parse_and_index_files(index, files, number_of_workers: number_of_workers) - end - say(" Done ", :green) - say("(#{time.round(2)}s)") + say("Loading #{kind} RBIs from #{dir}... ") + files = Dir.glob("#{dir}/**/*.rbi").sort + parse_and_index_files(index, files) + say(" Done", :green) end sig do params( index: RBI::Index, @@ -46,20 +46,17 @@ ).returns(T::Hash[String, T::Array[RBI::Node]]) end def duplicated_nodes_from_index(index, shim_rbi_dir:, todo_rbi_file:) duplicates = {} say("Looking for duplicates... ") - time = Benchmark.realtime do - index.keys.each do |key| - nodes = index[key] - next unless shims_or_todos_have_duplicates?(nodes, shim_rbi_dir: shim_rbi_dir, todo_rbi_file: todo_rbi_file) + index.keys.each do |key| + nodes = index[key] + next unless shims_or_todos_have_duplicates?(nodes, shim_rbi_dir: shim_rbi_dir, todo_rbi_file: todo_rbi_file) - duplicates[key] = nodes - end + duplicates[key] = nodes end - say(" Done ", :green) - say("(#{time.round(2)}s)") + say(" Done", :green) duplicates end sig { params(loc: RBI::Loc, path_prefix: T.nilable(String)).returns(String) } def location_to_payload_url(loc, path_prefix:) @@ -151,23 +148,25 @@ Kernel.exit(1) if parse_errors.any? end private - sig { params(index: RBI::Index, files: T::Array[String], number_of_workers: T.nilable(Integer)).void } - def parse_and_index_files(index, files, number_of_workers:) - executor = Executor.new(files, number_of_workers: number_of_workers) - - trees = executor.run_in_parallel do |file| - next if Spoom::Sorbet::Sigils.file_strictness(file) == "ignore" - - RBI::Parser.parse_file(file) - rescue RBI::ParseError => e - say_error("\nWarning: #{e} (#{e.location})", :yellow) + sig { params(index: RBI::Index, files: T::Array[String]).void } + def parse_and_index_files(index, files) + files.each do |file| + parse_and_index_file(index, file) end + end - index.visit_all(trees) + sig { params(index: RBI::Index, file: String).void } + def parse_and_index_file(index, file) + return if Spoom::Sorbet::Sigils.file_strictness(file) == "ignore" + + tree = RBI::Parser.parse_file(file) + index.visit(tree) + rescue RBI::ParseError => e + say_error("\nWarning: #{e} (#{e.location})", :yellow) end sig { params(nodes: T::Array[RBI::Node], shim_rbi_dir: String, todo_rbi_file: String).returns(T::Boolean) } def shims_or_todos_have_duplicates?(nodes, shim_rbi_dir:, todo_rbi_file:) return false if nodes.size == 1 @@ -176,10 +175,13 @@ return false if shims_or_todos.empty? shims_or_todos_empty_scopes = extract_empty_scopes(shims_or_todos) return true unless shims_or_todos_empty_scopes.empty? + mixins = extract_mixins(shims_or_todos) + return true unless mixins.empty? + props = extract_methods_and_attrs(shims_or_todos) return false if props.empty? shims_or_todos_with_sigs = extract_nodes_with_sigs(props) shims_or_todos_with_sigs.each do |shim_or_todo| @@ -211,9 +213,16 @@ sig { params(nodes: T::Array[RBI::Node]).returns(T::Array[T.any(RBI::Method, RBI::Attr)]) } def extract_methods_and_attrs(nodes) T.cast(nodes.select do |node| node.is_a?(RBI::Method) || node.is_a?(RBI::Attr) end, T::Array[T.any(RBI::Method, RBI::Attr)]) + end + + sig { params(nodes: T::Array[RBI::Node]).returns(T::Array[T.any(RBI::Mixin, RBI::RequiresAncestor)]) } + def extract_mixins(nodes) + T.cast(nodes.select do |node| + node.is_a?(RBI::Mixin) || node.is_a?(RBI::RequiresAncestor) + end, T::Array[T.all(RBI::Mixin, RBI::RequiresAncestor)]) end sig { params(nodes: T::Array[T.any(RBI::Method, RBI::Attr)]).returns(T::Array[T.any(RBI::Method, RBI::Attr)]) } def extract_nodes_with_sigs(nodes) nodes.reject { |node| node.sigs.empty? }