diff --git a/src/compiler/crystal/tools/doc/generator.cr b/src/compiler/crystal/tools/doc/generator.cr index 4c5988cccae5..e956ac8c3012 100644 --- a/src/compiler/crystal/tools/doc/generator.cr +++ b/src/compiler/crystal/tools/doc/generator.cr @@ -134,7 +134,7 @@ class Crystal::Doc::Generator end def must_include?(type : Crystal::Type) - return false if type.private? + return false if type.private? && !showdoc?(type) return false if nodoc? type return true if crystal_builtin?(type) @@ -215,6 +215,25 @@ class Crystal::Doc::Generator nodoc? obj.doc.try &.strip end + def showdoc?(str : String?) : Bool + return false if !str || !@program.wants_doc? + str.starts_with?(":showdoc:") + end + + def showdoc?(obj : Crystal::Type) + return false if !@program.wants_doc? + + if showdoc?(obj.doc.try &.strip) + return true + end + + obj.each_namespace do |ns| + return true if showdoc?(ns.doc.try &.strip) + end + + false + end + def crystal_builtin?(type) return false unless project_info.crystal_stdlib? # TODO: Enabling this allows links to `NoReturn` to work, but has two `NoReturn`s show up in the sidebar @@ -267,7 +286,7 @@ class Crystal::Doc::Generator types = [] of Constant parent.type.types?.try &.each_value do |type| - if type.is_a?(Const) && must_include?(type) && !type.private? + if type.is_a?(Const) && must_include?(type) && (!type.private? || showdoc?(type)) types << Constant.new(self, parent, type) end end @@ -296,7 +315,7 @@ class Crystal::Doc::Generator end def doc(obj : Type | Method | Macro | Constant) - doc = obj.doc + doc = obj.doc.try &.strip.lchop(":showdoc:") return if !doc && !has_doc_annotations?(obj) diff --git a/src/compiler/crystal/tools/doc/html/_method_detail.html b/src/compiler/crystal/tools/doc/html/_method_detail.html index 3fc3d5cd760b..1520d2a4a610 100644 --- a/src/compiler/crystal/tools/doc/html/_method_detail.html +++ b/src/compiler/crystal/tools/doc/html/_method_detail.html @@ -6,7 +6,7 @@

<% methods.each do |method| %>
- <%= method.abstract? ? "abstract " : "" %> + <%= method.abstract? ? "abstract " : "" %><%= method.visibility %> <%= method.kind %><%= method.name %><%= method.args_to_html %> # diff --git a/src/compiler/crystal/tools/doc/html/type.html b/src/compiler/crystal/tools/doc/html/type.html index 10c7e51fedd3..fb1dbbe94f13 100644 --- a/src/compiler/crystal/tools/doc/html/type.html +++ b/src/compiler/crystal/tools/doc/html/type.html @@ -19,7 +19,9 @@

<% if type.program? %> <%= type.full_name.gsub("::", "::") %> <% else %> - <%= type.abstract? ? "abstract " : ""%><%= type.kind %> <%= type.full_name.gsub("::", "::") %> + + <%= type.abstract? ? "abstract " : ""%><%= type.visibility %><%= type.kind %> + <%= type.full_name.gsub("::", "::") %> <% end %>

diff --git a/src/compiler/crystal/tools/doc/macro.cr b/src/compiler/crystal/tools/doc/macro.cr index 49b9c30795bc..629eccc2e225 100644 --- a/src/compiler/crystal/tools/doc/macro.cr +++ b/src/compiler/crystal/tools/doc/macro.cr @@ -54,6 +54,10 @@ class Crystal::Doc::Macro false end + def visibility + @type.visibility + end + def kind "macro " end diff --git a/src/compiler/crystal/tools/doc/method.cr b/src/compiler/crystal/tools/doc/method.cr index 069deb48ee61..7f71a9c42440 100644 --- a/src/compiler/crystal/tools/doc/method.cr +++ b/src/compiler/crystal/tools/doc/method.cr @@ -43,7 +43,7 @@ class Crystal::Doc::Method # This docs not include the "Description copied from ..." banner # in case it's needed. def doc - doc_info.doc + doc_info.doc.try &.strip.lchop(":showdoc:") end # Returns the type this method's docs are copied from, but @@ -135,6 +135,16 @@ class Crystal::Doc::Method end end + def visibility + case @def.visibility + in .public? + in .protected? + "protected " + in .private? + "private " + end + end + def constructor? return false unless @class_method return true if name == "new" @@ -323,6 +333,7 @@ class Crystal::Doc::Method builder.field "doc", doc unless doc.nil? builder.field "summary", formatted_summary unless formatted_summary.nil? builder.field "abstract", abstract? + builder.field "visibility", visibility if visibility builder.field "args", args unless args.empty? builder.field "args_string", args_to_s unless args.empty? builder.field "args_html", args_to_html unless args.empty? diff --git a/src/compiler/crystal/tools/doc/type.cr b/src/compiler/crystal/tools/doc/type.cr index 624c8f017fe7..69857cbd3306 100644 --- a/src/compiler/crystal/tools/doc/type.cr +++ b/src/compiler/crystal/tools/doc/type.cr @@ -81,6 +81,10 @@ class Crystal::Doc::Type @type.abstract? end + def visibility + @type.private? ? "private " : nil + end + def parents_of?(type) return false unless type @@ -181,7 +185,7 @@ class Crystal::Doc::Type defs = [] of Method @type.defs.try &.each do |def_name, defs_with_metadata| defs_with_metadata.each do |def_with_metadata| - next unless def_with_metadata.def.visibility.public? + next if !def_with_metadata.def.visibility.public? && !showdoc?(def_with_metadata.def) next unless @generator.must_include? def_with_metadata.def defs << method(def_with_metadata.def, false) @@ -192,6 +196,10 @@ class Crystal::Doc::Type end end + private def showdoc?(adef) + @generator.showdoc?(adef.doc.try &.strip) || @generator.showdoc?(@type) + end + private def sort_order(item) # Sort operators first, then alphanumeric (case-insensitive). {item.name[0].alphanumeric? ? 1 : 0, item.name.downcase} @@ -205,7 +213,7 @@ class Crystal::Doc::Type @type.metaclass.defs.try &.each_value do |defs_with_metadata| defs_with_metadata.each do |def_with_metadata| a_def = def_with_metadata.def - next unless a_def.visibility.public? + next if !def_with_metadata.def.visibility.public? && !showdoc?(def_with_metadata.def) body = a_def.body @@ -236,7 +244,9 @@ class Crystal::Doc::Type macros = [] of Macro @type.metaclass.macros.try &.each_value do |the_macros| the_macros.each do |a_macro| - if a_macro.visibility.public? && @generator.must_include? a_macro + next if !a_macro.visibility.public? && !showdoc?(a_macro) + + if @generator.must_include? a_macro macros << self.macro(a_macro) end end