Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions spec/compiler/crystal/tools/doc/generator_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,22 @@ describe Doc::Generator do
doc_method.formatted_doc.should eq %(<p>Some Method</p>\n<p><span class="flag #{color}">#{ann.upcase}</span> lorem ipsum</p>)
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 %(<p>Some Method</p>\n<p><span class="flag #{color}">#{ann.upcase} parameter <code>bar</code></span> lorem ipsum</p>)
end
end
end

describe "with no annotation, and no docs" do
Expand Down
36 changes: 26 additions & 10 deletions src/compiler/crystal/tools/doc/generator.cr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 = /<p>\s*#{flag}:?/
element_sub = %(<p><span class="flag #{FLAG_COLORS[flag]}">#{flag}</span> )
str.gsub(flag_regexp, element_sub)
# "DEPRECATED(parameter foo):"
str.gsub(/<p>\s*#{flag}\((.*)\):/, %(<p><span class="flag #{FLAG_COLORS[flag]}">#{flag} \\1</span> ))
# "DEPRECATED:"
.gsub(/<p>\s*#{flag}:?/, %(<p><span class="flag #{FLAG_COLORS[flag]}">#{flag}</span> ))
end
end

Expand All @@ -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

Expand Down