lib/sord/rbi_generator.rb in sord-0.10.0 vs lib/sord/rbi_generator.rb in sord-1.0.0

- old
+ new

@@ -37,10 +37,11 @@ @warnings = [] @replace_errors_with_untyped = options[:replace_errors_with_untyped] @replace_unresolved_with_untyped = options[:replace_unresolved_with_untyped] @keep_original_comments = options[:keep_original_comments] + @skip_constants = options[:skip_constants] # Hook the logger so that messages are added as comments to the RBI file Logging.add_hook do |type, msg, item| @current_object.add_comment_to_next_child("sord #{type} - #{msg}") end if options[:sord_comments] @@ -107,10 +108,12 @@ # separate method. Sorbet will handle it automatically. if meth.is_alias? next end + # Sort parameters + meth.parameters.reverse.sort! { |pair1, pair2| sort_params(pair1, pair2) } # This is better than iterating over YARD's "@param" tags directly # because it includes parameters without documentation # (The gsubs allow for better splat-argument compatibility) parameter_names_and_defaults_to_tags = meth.parameters.map do |name, default| [[name, default], meth.tags('param') @@ -233,14 +236,14 @@ params.each do |param| docs_array << '' if docs_array.last != '' && docs_array.length.positive? # Output params in the form of: # _@param_ `foo` — Lorem ipsum. # _@param_ `foo` - if param.text.nil? + if param.text.nil? || param.text == '' docs_array << "_@param_ `#{param.name}`" else - docs_array << "_@param_ `#{param.name}` — #{param.text}" + docs_array << "_@param_ `#{param.name}` — #{param.text.gsub("\n", " ")}" end end # Add @return tags (there could possibly be more than one, despite this not being supported) returns = parser.tags.select { |tag| tag.tag_name == 'return' && tag.is_a?(YARD::Tags::Tag) && !tag.text.nil? && tag.text.strip != '' } @@ -295,10 +298,13 @@ else docs_array << "_@see_ `#{see_tag.name}` — #{see_tag.text}" end end + # fix: yard text may contains multiple line. should deal \n. + # else generate text will be multiple line and only first line is commented + docs_array = docs_array.flat_map {|line| line.empty? ? [""] : line.split("\n")} m.add_comments(docs_array) end end end end @@ -319,11 +325,11 @@ : parent.create_module(item.name.to_s) @current_object.add_comments(item.docstring.all.split("\n")) add_mixins(item) add_methods(item) - add_constants(item) + add_constants(item) unless @skip_constants item.children.select { |x| [:class, :module].include?(x.type) } .each { |child| add_namespace(child) } @current_object = parent @@ -384,8 +390,48 @@ rescue Logging.error($!) $@.each do |line| puts " #{line}" end + end + + # Given two pairs of arrays representing method parameters, in the form + # of ["variable_name", "default_value"], sort the parameters so they're + # valid for Sorbet. Sorbet requires that, e.g. required kwargs go before + # optional kwargs. + # + # @param [Array] pair1 + # @param [Array] pair2 + # @return Integer + def sort_params(pair1, pair2) + pair1_type, pair2_type = [pair1, pair2].map do |pair| + if pair[0].start_with?('&') + :blk + elsif pair[0].start_with?('**') + :doublesplat + elsif pair[0].start_with?('*') + :splat + elsif !pair[0].end_with?(':') && pair[1].nil? + :required_ordered_param + elsif !pair[0].end_with?(':') && !pair[1].nil? + :optional_ordered_param + elsif pair[0].end_with?(':') && pair[1].nil? + :required_kwarg + elsif pair[0].end_with?(':') && !pair[1].nil? + :optional_kwarg + end + end + + pair_type_order = { + required_ordered_param: 1, + optional_ordered_param: 2, + splat: 3, + required_kwarg: 4, + optional_kwarg: 5, + doublesplat: 6, + blk: 7 + } + + return pair_type_order[pair1_type] <=> pair_type_order[pair2_type] end end end