diff --git a/spec/compiler/crystal/tools/doc/generator_spec.cr b/spec/compiler/crystal/tools/doc/generator_spec.cr index b7bbd260293b..0b64c6005b74 100644 --- a/spec/compiler/crystal/tools/doc/generator_spec.cr +++ b/spec/compiler/crystal/tools/doc/generator_spec.cr @@ -204,6 +204,22 @@ describe Doc::Generator do doc_method.formatted_doc.should eq %(

Some Method

\n

#{ann.upcase} lorem ipsum

) end end + + describe "with #{ann} annotation in parameter" do + it "should generate the #{ann} tag" do + program = Program.new + generator = Doc::Generator.new program, ["."] + doc_type = Doc::Type.new generator, program + + a_def = Def.new "foo" + a_def.doc = "Some Method" + arg = Arg.new("bar") + arg.add_annotation(program.types[ann].as(Crystal::AnnotationType), Annotation.new(Crystal::Path.new(ann), ["lorem ipsum".string] of ASTNode)) + a_def.args << arg + doc_method = Doc::Method.new generator, doc_type, a_def, false + doc_method.formatted_doc.should eq %(

Some Method

\n

#{ann.upcase} parameter bar lorem ipsum

) + end + end end describe "with no annotation, and no docs" do diff --git a/src/compiler/crystal/tools/doc/generator.cr b/src/compiler/crystal/tools/doc/generator.cr index e069492e090d..38bc0559b213 100644 --- a/src/compiler/crystal/tools/doc/generator.cr +++ b/src/compiler/crystal/tools/doc/generator.cr @@ -315,12 +315,16 @@ class Crystal::Doc::Generator end def has_doc_annotations?(obj) - obj.annotations(@program.deprecated_annotation) || obj.annotations(@program.experimental_annotation) + obj.annotations(@program.deprecated_annotation) || + obj.annotations(@program.experimental_annotation) || + obj.as?(Method).try &.def.args.any? { |arg| has_doc_annotations?(arg) } end def doc(context, string) string = isolate_flag_lines string - string += build_flag_lines_from_annotations context + if annotations = build_flag_lines_from_annotations context + string += "\n\n" + annotations + end markdown = render_markdown(context, string) generate_flags markdown end @@ -341,9 +345,10 @@ class Crystal::Doc::Generator # Assumes that flag keywords are at the beginning of respective `p` element def generate_flags(string) FLAGS.reduce(string) do |str, flag| - flag_regexp = /

\s*#{flag}:?/ - element_sub = %(

#{flag} ) - str.gsub(flag_regexp, element_sub) + # "DEPRECATED(parameter foo):" + str.gsub(/

\s*#{flag}\((.*)\):/, %(

#{flag} \\1 )) + # "DEPRECATED:" + .gsub(/

\s*#{flag}:?/, %(

#{flag} )) end end @@ -364,23 +369,34 @@ class Crystal::Doc::Generator end def build_flag_lines_from_annotations(context) - first = true String.build do |io| if anns = context.annotations(@program.deprecated_annotation) anns.each do |ann| - io << "\n\n" if first - first = false io << "DEPRECATED: #{DeprecatedAnnotation.from(ann).message}\n\n" end end if anns = context.annotations(@program.experimental_annotation) anns.each do |ann| - io << "\n\n" if first - first = false io << "EXPERIMENTAL: #{ExperimentalAnnotation.from(ann).message}\n\n" end end + + if context.is_a?(Method) + context.def.args.each do |arg| + if anns = arg.annotations(@program.deprecated_annotation) + anns.each do |ann| + io << "DEPRECATED(parameter `#{arg.name}`): #{DeprecatedAnnotation.from(ann).message}\n\n" + end + end + + if anns = arg.annotations(@program.experimental_annotation) + anns.each do |ann| + io << "EXPERIMENTAL(parameter `#{arg.name}`): #{ExperimentalAnnotation.from(ann).message}\n\n" + end + end + end + end end end