From e483706a3f9b778febeb86d701957275457e91f9 Mon Sep 17 00:00:00 2001 From: Oleh Prypin Date: Sun, 20 Dec 2020 02:43:49 +0100 Subject: [PATCH 1/7] s/links/html/ --- src/compiler/crystal/tools/doc/method.cr | 22 +++--- src/compiler/crystal/tools/doc/type.cr | 86 ++++++++++++------------ 2 files changed, 54 insertions(+), 54 deletions(-) diff --git a/src/compiler/crystal/tools/doc/method.cr b/src/compiler/crystal/tools/doc/method.cr index 320f270799bd..ea0ae15af345 100644 --- a/src/compiler/crystal/tools/doc/method.cr +++ b/src/compiler/crystal/tools/doc/method.cr @@ -211,14 +211,14 @@ class Crystal::Doc::Method end def args_to_s(io : IO) : Nil - args_to_html(io, links: false) + args_to_html(io, html: false) end def args_to_html String.build { |io| args_to_html io } end - def args_to_html(io : IO, links : Bool = true) : Nil + def args_to_html(io : IO, html : Bool = true) : Nil return_type = self.return_type return unless has_args? || return_type @@ -229,7 +229,7 @@ class Crystal::Doc::Method @def.args.each_with_index do |arg, i| io << ", " if printed io << '*' if @def.splat_index == i - arg_to_html arg, io, links: links + arg_to_html arg, io, html: html printed = true end if double_splat = @def.double_splat @@ -241,7 +241,7 @@ class Crystal::Doc::Method if block_arg = @def.block_arg io << ", " if printed io << '&' - arg_to_html block_arg, io, links: links + arg_to_html block_arg, io, html: html elsif @def.yields io << ", " if printed io << '&' @@ -254,10 +254,10 @@ class Crystal::Doc::Method # Nothing to do when ASTNode io << " : " - node_to_html return_type, io, links: links + node_to_html return_type, io, html: html when Crystal::Type io << " : " - @type.type_to_html return_type, io, links: links + @type.type_to_html return_type, io, html: html end if free_vars = @def.free_vars @@ -268,7 +268,7 @@ class Crystal::Doc::Method io end - def arg_to_html(arg : Arg, io, links = true) + def arg_to_html(arg : Arg, io, html = true) if arg.external_name != arg.name name = arg.external_name.presence || "_" if Symbol.needs_quotes? name @@ -283,10 +283,10 @@ class Crystal::Doc::Method if restriction = arg.restriction io << " : " - node_to_html restriction, io, links: links + node_to_html restriction, io, html: html elsif type = arg.type? io << " : " - @type.type_to_html type, io, links: links + @type.type_to_html type, io, html: html end if default_value = arg.default_value @@ -295,8 +295,8 @@ class Crystal::Doc::Method end end - def node_to_html(node, io, links = true) - @type.node_to_html node, io, links: links + def node_to_html(node, io, html = true) + @type.node_to_html node, io, html: html end def must_be_included? diff --git a/src/compiler/crystal/tools/doc/type.cr b/src/compiler/crystal/tools/doc/type.cr index 5a0628baf59a..d5a233b93d6e 100644 --- a/src/compiler/crystal/tools/doc/type.cr +++ b/src/compiler/crystal/tools/doc/type.cr @@ -473,7 +473,7 @@ class Crystal::Doc::Type String.build { |io| node_to_html node, io } end - def node_to_html(node : Path, io, links = true) + def node_to_html(node : Path, io, html = true) match = lookup_path(node) if match # If the path is global, search a local path and @@ -486,57 +486,57 @@ class Crystal::Doc::Type node.global = true unless remove_colons end - type_to_html match, io, node.to_s, links: links + type_to_html match, io, node.to_s, html: html node.global = true if remove_colons else io << node end end - def node_to_html(node : Generic, io, links = true) - node_to_html node.name, io, links: links + def node_to_html(node : Generic, io, html = true) + node_to_html node.name, io, html: html io << '(' node.type_vars.join(io, ", ") do |type_var| - node_to_html type_var, io, links: links + node_to_html type_var, io, html: html end io << ')' end - def node_to_html(node : ProcNotation, io, links = true) + def node_to_html(node : ProcNotation, io, html = true) if inputs = node.inputs inputs.join(io, ", ") do |input| - node_to_html input, io, links: links + node_to_html input, io, html: html end end io << " -> " if output = node.output - node_to_html output, io, links: links + node_to_html output, io, html: html end end - def node_to_html(node : Union, io, links = true) + def node_to_html(node : Union, io, html = true) # See if it's a nilable type if node.types.size == 2 # See if first type is Nil if nil_type?(node.types[0]) - return nilable_type_to_html node.types[1], io, links: links + return nilable_type_to_html node.types[1], io, html: html elsif nil_type?(node.types[1]) - return nilable_type_to_html node.types[0], io, links: links + return nilable_type_to_html node.types[0], io, html: html end end node.types.join(io, " | ") do |elem| - node_to_html elem, io, links: links + node_to_html elem, io, html: html end end - private def nilable_type_to_html(node : ASTNode, io, links) - node_to_html node, io, links: links + private def nilable_type_to_html(node : ASTNode, io, html) + node_to_html node, io, html: html io << '?' end - private def nilable_type_to_html(type : Crystal::Type, io, text, links) - type_to_html(type, io, text, links: links) + private def nilable_type_to_html(type : Crystal::Type, io, text, html) + type_to_html(type, io, text, html: html) io << '?' end @@ -547,11 +547,11 @@ class Crystal::Doc::Type match && match.type == @generator.program.nil_type end - def node_to_html(node, io, links = true) + def node_to_html(node, io, html = true) io << Highlighter.highlight(node.to_s) end - def node_to_html(node : Underscore, io, links = true) + def node_to_html(node : Underscore, io, html = true) io << '_' end @@ -560,14 +560,14 @@ class Crystal::Doc::Type String.build { |io| type_to_html(type, io) } end - def type_to_html(type : Crystal::UnionType, io, text = nil, links = true) + def type_to_html(type : Crystal::UnionType, io, text = nil, html = true) has_type_splat = type.union_types.any? &.is_a?(TypeSplat) if !has_type_splat && type.union_types.size == 2 if type.union_types[0].nil_type? - return nilable_type_to_html(type.union_types[1], io, text, links) + return nilable_type_to_html(type.union_types[1], io, text, html) elsif type.union_types[1].nil_type? - return nilable_type_to_html(type.union_types[0], io, text, links) + return nilable_type_to_html(type.union_types[0], io, text, html) end end @@ -579,30 +579,30 @@ class Crystal::Doc::Type end type.union_types.join(io, separator) do |union_type| - type_to_html union_type, io, text, links: links + type_to_html union_type, io, text, html: html end io << ')' if has_type_splat end - def type_to_html(type : Crystal::ProcInstanceType, io, text = nil, links = true) + def type_to_html(type : Crystal::ProcInstanceType, io, text = nil, html = true) type.arg_types.join(io, ", ") do |arg_type| - type_to_html arg_type, io, links: links + type_to_html arg_type, io, html: html end io << " -> " return_type = type.return_type - type_to_html return_type, io, links: links unless return_type.void? + type_to_html return_type, io, html: html unless return_type.void? end - def type_to_html(type : Crystal::TupleInstanceType, io, text = nil, links = true) + def type_to_html(type : Crystal::TupleInstanceType, io, text = nil, html = true) io << '{' type.tuple_types.join(io, ", ") do |tuple_type| - type_to_html tuple_type, io, links: links + type_to_html tuple_type, io, html: html end io << '}' end - def type_to_html(type : Crystal::NamedTupleInstanceType, io, text = nil, links = true) + def type_to_html(type : Crystal::NamedTupleInstanceType, io, text = nil, html = true) io << '{' type.entries.join(io, ", ") do |entry| if Symbol.needs_quotes?(entry.name) @@ -611,17 +611,17 @@ class Crystal::Doc::Type io << entry.name end io << ": " - type_to_html entry.type, io, links: links + type_to_html entry.type, io, html: html end io << '}' end - def type_to_html(type : Crystal::GenericInstanceType, io, text = nil, links = true) + def type_to_html(type : Crystal::GenericInstanceType, io, text = nil, html = true) has_link_in_type_vars = type.type_vars.any? { |(name, type_var)| type_has_link? type_var.as?(Var).try(&.type) || type_var } generic_type = @generator.type(type.generic_type) must_be_included = generic_type.must_be_included? - if must_be_included && links + if must_be_included && html io << %() @@ -633,30 +633,30 @@ class Crystal::Doc::Type generic_type.full_name_without_type_vars(io) end - io << "" if must_be_included && links && has_link_in_type_vars + io << "" if must_be_included && html && has_link_in_type_vars io << '(' type.type_vars.values.join(io, ", ") do |type_var| case type_var when Var - type_to_html type_var.type, io, links: links + type_to_html type_var.type, io, html: html else - type_to_html type_var, io, links: links + type_to_html type_var, io, html: html end end io << ')' - io << "" if must_be_included && links && !has_link_in_type_vars + io << "" if must_be_included && html && !has_link_in_type_vars end - def type_to_html(type : Crystal::VirtualType, io, text = nil, links = true) - type_to_html type.base_type, io, text, links: links + def type_to_html(type : Crystal::VirtualType, io, text = nil, html = true) + type_to_html type.base_type, io, text, html: html end - def type_to_html(type : Crystal::Type, io, text = nil, links = true) + def type_to_html(type : Crystal::Type, io, text = nil, html = true) type = @generator.type(type) if type.must_be_included? - if links + if html io << %() @@ -666,7 +666,7 @@ class Crystal::Doc::Type else type.full_name(io) end - if links + if html io << "" end else @@ -678,11 +678,11 @@ class Crystal::Doc::Type end end - def type_to_html(type : Type, io, text = nil, links = true) - type_to_html type.type, io, text, links: links + def type_to_html(type : Type, io, text = nil, html = true) + type_to_html type.type, io, text, html: html end - def type_to_html(type : ASTNode, io, text = nil, links = true) + def type_to_html(type : ASTNode, io, text = nil, html = true) type.to_s io end From 77eb361c5490856db0359e083fa9a14d956bcb60 Mon Sep 17 00:00:00 2001 From: Oleh Prypin Date: Sun, 20 Dec 2020 02:17:07 +0100 Subject: [PATCH 2/7] Fix consistency between arg_to_s and arg_to_html --- spec/compiler/crystal/tools/doc/macro_spec.cr | 29 +++++++++------ .../compiler/crystal/tools/doc/method_spec.cr | 35 ++++++++++++------- src/compiler/crystal/tools/doc/macro.cr | 32 +++++++++++------ src/compiler/crystal/tools/doc/method.cr | 12 +++++-- src/compiler/crystal/tools/doc/type.cr | 6 +++- 5 files changed, 77 insertions(+), 37 deletions(-) diff --git a/spec/compiler/crystal/tools/doc/macro_spec.cr b/spec/compiler/crystal/tools/doc/macro_spec.cr index 545dc9019cd8..8fc80760250f 100644 --- a/spec/compiler/crystal/tools/doc/macro_spec.cr +++ b/spec/compiler/crystal/tools/doc/macro_spec.cr @@ -1,5 +1,10 @@ require "../../../spec_helper" +private def assert_args_to_s(item, to_s_output, to_html_output = to_s_output, file = __FILE__, line = __LINE__) + item.args_to_s.should eq(to_s_output), file, line + item.args_to_html.should eq(to_html_output), file, line +end + describe Doc::Macro do describe "args_to_s" do it "shows simple args" do @@ -9,7 +14,7 @@ describe Doc::Macro do a_macro = Macro.new "foo", ["foo".arg, "bar".arg] doc_macro = Doc::Macro.new generator, doc_type, a_macro - doc_macro.args_to_s.should eq("(foo, bar)") + assert_args_to_s(doc_macro, "(foo, bar)") end it "shows splat arg" do @@ -19,7 +24,7 @@ describe Doc::Macro do a_macro = Macro.new "foo", ["foo".arg], splat_index: 0 doc_macro = Doc::Macro.new generator, doc_type, a_macro - doc_macro.args_to_s.should eq("(*foo)") + assert_args_to_s(doc_macro, "(*foo)") end it "shows simple arg and splat arg" do @@ -29,7 +34,7 @@ describe Doc::Macro do a_macro = Macro.new "foo", ["foo".arg, "bar".arg], splat_index: 1 doc_macro = Doc::Macro.new generator, doc_type, a_macro - doc_macro.args_to_s.should eq("(foo, *bar)") + assert_args_to_s(doc_macro, "(foo, *bar)") end it "shows double splat arg" do @@ -39,7 +44,7 @@ describe Doc::Macro do a_macro = Macro.new "foo", double_splat: "foo".arg doc_macro = Doc::Macro.new generator, doc_type, a_macro - doc_macro.args_to_s.should eq("(**foo)") + assert_args_to_s(doc_macro, "(**foo)") end it "shows double splat arg" do @@ -49,7 +54,7 @@ describe Doc::Macro do a_macro = Macro.new "foo", double_splat: "foo".arg doc_macro = Doc::Macro.new generator, doc_type, a_macro - doc_macro.args_to_s.should eq("(**foo)") + assert_args_to_s(doc_macro, "(**foo)") end it "shows simple arg and double splat arg" do @@ -59,7 +64,7 @@ describe Doc::Macro do a_macro = Macro.new "foo", ["foo".arg], double_splat: "bar".arg doc_macro = Doc::Macro.new generator, doc_type, a_macro - doc_macro.args_to_s.should eq("(foo, **bar)") + assert_args_to_s(doc_macro, "(foo, **bar)") end it "shows block arg" do @@ -69,7 +74,7 @@ describe Doc::Macro do a_macro = Macro.new "foo", block_arg: "foo".arg doc_macro = Doc::Macro.new generator, doc_type, a_macro - doc_macro.args_to_s.should eq("(&foo)") + assert_args_to_s(doc_macro, "(&foo)") end it "shows simple arg and block arg" do @@ -79,7 +84,7 @@ describe Doc::Macro do a_macro = Macro.new "foo", ["foo".arg], block_arg: "bar".arg doc_macro = Doc::Macro.new generator, doc_type, a_macro - doc_macro.args_to_s.should eq("(foo, &bar)") + assert_args_to_s(doc_macro, "(foo, &bar)") end it "shows external name of arg" do @@ -89,7 +94,7 @@ describe Doc::Macro do a_macro = Macro.new "foo", ["foo".arg(external_name: "bar")] doc_macro = Doc::Macro.new generator, doc_type, a_macro - doc_macro.args_to_s.should eq("(bar foo)") + assert_args_to_s(doc_macro, "(bar foo)") end it "shows external name of arg with quotes and escaping" do @@ -99,7 +104,9 @@ describe Doc::Macro do a_macro = Macro.new "foo", ["foo".arg(external_name: "<<-< uouo fish life")] doc_macro = Doc::Macro.new generator, doc_type, a_macro - doc_macro.args_to_s.should eq("("<<-< uouo fish life" foo)") + assert_args_to_s(doc_macro, + %(("<<-< uouo fish life" foo)), + "("<<-< uouo fish life" foo)") end it "shows default value with highlighting" do @@ -109,7 +116,7 @@ describe Doc::Macro do a_macro = Macro.new "foo", ["foo".arg(default_value: 1.int32)] doc_macro = Doc::Macro.new generator, doc_type, a_macro - doc_macro.args_to_s.should eq(%((foo = 1))) + assert_args_to_s(doc_macro, %((foo = 1)), %((foo = 1))) end end end diff --git a/spec/compiler/crystal/tools/doc/method_spec.cr b/spec/compiler/crystal/tools/doc/method_spec.cr index 43af60efea78..6a97210d5de7 100644 --- a/spec/compiler/crystal/tools/doc/method_spec.cr +++ b/spec/compiler/crystal/tools/doc/method_spec.cr @@ -1,5 +1,10 @@ require "../../../spec_helper" +private def assert_args_to_s(item, to_s_output, to_html_output = to_s_output, file = __FILE__, line = __LINE__) + item.args_to_s.should eq(to_s_output), file, line + item.args_to_html.should eq(to_html_output), file, line +end + describe Doc::Method do describe "args_to_s" do it "shows simple args" do @@ -9,7 +14,7 @@ describe Doc::Method do a_def = Def.new "foo", ["foo".arg, "bar".arg] doc_method = Doc::Method.new generator, doc_type, a_def, false - doc_method.args_to_s.should eq("(foo, bar)") + assert_args_to_s(doc_method, "(foo, bar)") end it "shows splat args" do @@ -19,7 +24,7 @@ describe Doc::Method do a_def = Def.new "foo", ["foo".arg], splat_index: 0 doc_method = Doc::Method.new generator, doc_type, a_def, false - doc_method.args_to_s.should eq("(*foo)") + assert_args_to_s(doc_method, "(*foo)") end it "shows underscore restriction" do @@ -29,7 +34,7 @@ describe Doc::Method do a_def = Def.new "foo", ["foo".arg(restriction: Crystal::Underscore.new)], splat_index: 0 doc_method = Doc::Method.new generator, doc_type, a_def, false - doc_method.args_to_s.should eq("(*foo : _)") + assert_args_to_s(doc_method, "(*foo : _)") end it "shows double splat args" do @@ -39,7 +44,7 @@ describe Doc::Method do a_def = Def.new "foo", double_splat: "foo".arg doc_method = Doc::Method.new generator, doc_type, a_def, false - doc_method.args_to_s.should eq("(**foo)") + assert_args_to_s(doc_method, "(**foo)") end it "shows block args" do @@ -49,7 +54,7 @@ describe Doc::Method do a_def = Def.new "foo", block_arg: "foo".arg doc_method = Doc::Method.new generator, doc_type, a_def, false - doc_method.args_to_s.should eq("(&foo)") + assert_args_to_s(doc_method, "(&foo)") end it "shows block args with underscore" do @@ -59,7 +64,7 @@ describe Doc::Method do a_def = Def.new "foo", block_arg: "foo".arg(restriction: Crystal::ProcNotation.new(([Crystal::Underscore.new] of Crystal::ASTNode), Crystal::Underscore.new)) doc_method = Doc::Method.new generator, doc_type, a_def, false - doc_method.args_to_s.should eq("(&foo : _ -> _)") + assert_args_to_s(doc_method, "(&foo : _ -> _)") end it "shows block args if a def has `yield`" do @@ -69,7 +74,7 @@ describe Doc::Method do a_def = Def.new "foo", yields: 1 doc_method = Doc::Method.new generator, doc_type, a_def, false - doc_method.args_to_s.should eq("(&)") + assert_args_to_s(doc_method, "(&)") end it "shows return type restriction" do @@ -79,7 +84,7 @@ describe Doc::Method do a_def = Def.new "foo", return_type: "Foo".path doc_method = Doc::Method.new generator, doc_type, a_def, false - doc_method.args_to_s.should eq(" : Foo") + assert_args_to_s(doc_method, " : Foo") end it "shows args and return type restriction" do @@ -89,7 +94,7 @@ describe Doc::Method do a_def = Def.new "foo", ["foo".arg], return_type: "Foo".path doc_method = Doc::Method.new generator, doc_type, a_def, false - doc_method.args_to_s.should eq("(foo) : Foo") + assert_args_to_s(doc_method, "(foo) : Foo") end it "shows external name of arg" do @@ -99,7 +104,7 @@ describe Doc::Method do a_def = Def.new "foo", ["foo".arg(external_name: "bar")] doc_method = Doc::Method.new generator, doc_type, a_def, false - doc_method.args_to_s.should eq("(bar foo)") + assert_args_to_s(doc_method, "(bar foo)") end it "shows external name of arg with quotes and escaping" do @@ -109,7 +114,9 @@ describe Doc::Method do a_def = Def.new "foo", ["foo".arg(external_name: "<<-< uouo fish life")] doc_method = Doc::Method.new generator, doc_type, a_def, false - doc_method.args_to_s.should eq("("<<-< uouo fish life" foo)") + assert_args_to_s(doc_method, + %(("<<-< uouo fish life" foo)), + "("<<-< uouo fish life" foo)") end it "shows typeof restriction of arg with highlighting" do @@ -119,7 +126,9 @@ describe Doc::Method do a_def = Def.new "foo", ["foo".arg(restriction: TypeOf.new([1.int32] of ASTNode))] doc_method = Doc::Method.new generator, doc_type, a_def, false - doc_method.args_to_s.should eq(%((foo : typeof(1)))) + assert_args_to_s(doc_method, + %((foo : typeof(1))), + %((foo : typeof(1)))) end it "shows default value of arg with highlighting" do @@ -129,7 +138,7 @@ describe Doc::Method do a_def = Def.new "foo", ["foo".arg(default_value: 1.int32)] doc_method = Doc::Method.new generator, doc_type, a_def, false - doc_method.args_to_s.should eq(%((foo = 1))) + assert_args_to_s(doc_method, %((foo = 1)), %((foo = 1))) end end diff --git a/src/compiler/crystal/tools/doc/macro.cr b/src/compiler/crystal/tools/doc/macro.cr index e7072d6e611d..e01d9889e662 100644 --- a/src/compiler/crystal/tools/doc/macro.cr +++ b/src/compiler/crystal/tools/doc/macro.cr @@ -68,6 +68,14 @@ class Crystal::Doc::Macro end def args_to_s(io : IO) : Nil + args_to_html(io, html: false) + end + + def args_to_html + String.build { |io| args_to_html io } + end + + def args_to_html(io : IO, html : Bool = true) : Nil return unless has_args? printed = false @@ -76,31 +84,35 @@ class Crystal::Doc::Macro @macro.args.each_with_index do |arg, i| io << ", " if printed io << '*' if @macro.splat_index == i - arg_to_s arg, io + arg_to_html arg, io, html: html printed = true end if double_splat = @macro.double_splat io << ", " if printed io << "**" - arg_to_s double_splat, io + arg_to_html double_splat, io, html: html printed = true end if block_arg = @macro.block_arg io << ", " if printed io << '&' - arg_to_s block_arg, io + arg_to_html block_arg, io, html: html end io << ')' end - def arg_to_s(arg : Arg, io : IO) : Nil + def arg_to_html(arg : Arg, io, html = true) if arg.external_name != arg.name name = arg.external_name.presence || "_" if Symbol.needs_quotes? name - HTML.escape name.inspect, io + if html + HTML.escape name.inspect, io + else + name.inspect io + end else io << name end @@ -113,7 +125,11 @@ class Crystal::Doc::Macro if default_value = arg.default_value io << " = " - io << Highlighter.highlight(default_value.to_s) + if html + io << Highlighter.highlight(default_value.to_s) + else + io << default_value + end end end @@ -121,10 +137,6 @@ class Crystal::Doc::Macro !@macro.args.empty? || @macro.double_splat || @macro.block_arg end - def args_to_html - args_to_s - end - def must_be_included? @generator.must_include? @macro end diff --git a/src/compiler/crystal/tools/doc/method.cr b/src/compiler/crystal/tools/doc/method.cr index ea0ae15af345..d5ee682630ef 100644 --- a/src/compiler/crystal/tools/doc/method.cr +++ b/src/compiler/crystal/tools/doc/method.cr @@ -272,7 +272,11 @@ class Crystal::Doc::Method if arg.external_name != arg.name name = arg.external_name.presence || "_" if Symbol.needs_quotes? name - HTML.escape name.inspect, io + if html + HTML.escape name.inspect, io + else + name.inspect io + end else io << name end @@ -291,7 +295,11 @@ class Crystal::Doc::Method if default_value = arg.default_value io << " = " - io << Highlighter.highlight(default_value.to_s) + if html + io << Highlighter.highlight(default_value.to_s) + else + io << default_value + end end end diff --git a/src/compiler/crystal/tools/doc/type.cr b/src/compiler/crystal/tools/doc/type.cr index d5a233b93d6e..ab4af44cb3f4 100644 --- a/src/compiler/crystal/tools/doc/type.cr +++ b/src/compiler/crystal/tools/doc/type.cr @@ -548,7 +548,11 @@ class Crystal::Doc::Type end def node_to_html(node, io, html = true) - io << Highlighter.highlight(node.to_s) + if html + io << Highlighter.highlight(node.to_s) + else + io << node + end end def node_to_html(node : Underscore, io, html = true) From 6a8c3a98c90475daab478b8d2026898bbc3437be Mon Sep 17 00:00:00 2001 From: Oleh Prypin Date: Sun, 20 Dec 2020 02:34:24 +0100 Subject: [PATCH 3/7] Doc JSON: expose HTML-annotated versions of linkifiable strings --- src/compiler/crystal/tools/doc/macro.cr | 1 + src/compiler/crystal/tools/doc/method.cr | 1 + src/compiler/crystal/tools/doc/type.cr | 1 + 3 files changed, 3 insertions(+) diff --git a/src/compiler/crystal/tools/doc/macro.cr b/src/compiler/crystal/tools/doc/macro.cr index e01d9889e662..8e424b595961 100644 --- a/src/compiler/crystal/tools/doc/macro.cr +++ b/src/compiler/crystal/tools/doc/macro.cr @@ -151,6 +151,7 @@ class Crystal::Doc::Macro builder.field "abstract", abstract? builder.field "args", args builder.field "args_string", args_to_s + builder.field "args_html", args_to_html builder.field "source_link", source_link builder.field "def", self.macro end diff --git a/src/compiler/crystal/tools/doc/method.cr b/src/compiler/crystal/tools/doc/method.cr index d5ee682630ef..c2f20bf63984 100644 --- a/src/compiler/crystal/tools/doc/method.cr +++ b/src/compiler/crystal/tools/doc/method.cr @@ -325,6 +325,7 @@ class Crystal::Doc::Method builder.field "abstract", abstract? builder.field "args", args builder.field "args_string", args_to_s + builder.field "args_html", args_to_html builder.field "source_link", source_link builder.field "def", self.def end diff --git a/src/compiler/crystal/tools/doc/type.cr b/src/compiler/crystal/tools/doc/type.cr index ab4af44cb3f4..298e06193623 100644 --- a/src/compiler/crystal/tools/doc/type.cr +++ b/src/compiler/crystal/tools/doc/type.cr @@ -776,6 +776,7 @@ class Crystal::Doc::Type builder.field "enum", enum? builder.field "alias", alias? builder.field "aliased", alias_definition.to_s + builder.field "aliased_html", formatted_alias_definition builder.field "const", const? builder.field "constants", constants builder.field "included_modules" do From a881d9cd8d45c8d75ad8cbd212b2f0f90cd0e7d4 Mon Sep 17 00:00:00 2001 From: Oleh Prypin Date: Sun, 20 Dec 2020 03:30:57 +0100 Subject: [PATCH 4/7] Undo the aliased_html addition --- src/compiler/crystal/tools/doc/type.cr | 1 - 1 file changed, 1 deletion(-) diff --git a/src/compiler/crystal/tools/doc/type.cr b/src/compiler/crystal/tools/doc/type.cr index 298e06193623..ab4af44cb3f4 100644 --- a/src/compiler/crystal/tools/doc/type.cr +++ b/src/compiler/crystal/tools/doc/type.cr @@ -776,7 +776,6 @@ class Crystal::Doc::Type builder.field "enum", enum? builder.field "alias", alias? builder.field "aliased", alias_definition.to_s - builder.field "aliased_html", formatted_alias_definition builder.field "const", const? builder.field "constants", constants builder.field "included_modules" do From 63b391af818b1398fc9b69b9449a0275074a02c1 Mon Sep 17 00:00:00 2001 From: Oleh Prypin Date: Sat, 2 Jan 2021 14:10:32 +0100 Subject: [PATCH 5/7] Fix escaping anchor ids --- src/compiler/crystal/tools/doc/macro.cr | 3 +-- src/compiler/crystal/tools/doc/method.cr | 5 ++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/compiler/crystal/tools/doc/macro.cr b/src/compiler/crystal/tools/doc/macro.cr index 3c8b09cf7b9e..07a667a69dcd 100644 --- a/src/compiler/crystal/tools/doc/macro.cr +++ b/src/compiler/crystal/tools/doc/macro.cr @@ -143,8 +143,7 @@ class Crystal::Doc::Macro def to_json(builder : JSON::Builder) builder.object do - builder.field "id", id - builder.field "html_id", html_id + builder.field "html_id", id builder.field "name", name builder.field "doc", doc builder.field "summary", formatted_summary diff --git a/src/compiler/crystal/tools/doc/method.cr b/src/compiler/crystal/tools/doc/method.cr index 9560a1495856..ccaac1c8feb1 100644 --- a/src/compiler/crystal/tools/doc/method.cr +++ b/src/compiler/crystal/tools/doc/method.cr @@ -194,7 +194,7 @@ class Crystal::Doc::Method end def html_id - id + HTML.escape(id) end def anchor @@ -317,8 +317,7 @@ class Crystal::Doc::Method def to_json(builder : JSON::Builder) builder.object do - builder.field "id", id - builder.field "html_id", html_id + builder.field "html_id", id builder.field "name", name builder.field "doc", doc builder.field "summary", formatted_summary From c359f8f10a83ff14c07579e9b264de4e1a57e813 Mon Sep 17 00:00:00 2001 From: Oleh Prypin Date: Sat, 2 Jan 2021 13:56:54 +0100 Subject: [PATCH 6/7] Restore the ability to get HTML without links but still highlighted --- .../tools/doc/html/_method_summary.html | 2 +- .../tools/doc/html/_methods_inherited.html | 2 +- src/compiler/crystal/tools/doc/item.cr | 14 +++++++ src/compiler/crystal/tools/doc/macro.cr | 18 ++++---- src/compiler/crystal/tools/doc/method.cr | 20 ++++----- src/compiler/crystal/tools/doc/type.cr | 42 +++++++++---------- 6 files changed, 56 insertions(+), 42 deletions(-) diff --git a/src/compiler/crystal/tools/doc/html/_method_summary.html b/src/compiler/crystal/tools/doc/html/_method_summary.html index b783abf13968..f59435ea5459 100644 --- a/src/compiler/crystal/tools/doc/html/_method_summary.html +++ b/src/compiler/crystal/tools/doc/html/_method_summary.html @@ -6,7 +6,7 @@

    <% methods.each do |method| %>
  • - <%= method.prefix %><%= method.name %><%= method.args_to_s %> + <%= method.prefix %><%= method.name %><%= method.args_to_html(:highlight) %> <% if summary = method.formatted_summary %>
    <%= summary %>
    <% end %> diff --git a/src/compiler/crystal/tools/doc/html/_methods_inherited.html b/src/compiler/crystal/tools/doc/html/_methods_inherited.html index e12b861636ae..8b7291a3e597 100644 --- a/src/compiler/crystal/tools/doc/html/_methods_inherited.html +++ b/src/compiler/crystal/tools/doc/html/_methods_inherited.html @@ -4,7 +4,7 @@

    <%= label %> methods inherited from <%= ancestor.kind %> <%= ancestor. <% i = 0 %> <% method_groups.each do |method_name, methods| %> - <%= methods.map { |method| method.name + method.args_to_s } .join("
    ") %>
    + <%= methods.map { |method| method.name + method.args_to_html(:highlight) } .join("
    ") %>
    <%= method_name %>
    <%= ", " if i != method_groups.size - 1 %> <% i += 1 %> <% end %> diff --git a/src/compiler/crystal/tools/doc/item.cr b/src/compiler/crystal/tools/doc/item.cr index ef2b5abee8b9..6e20da144168 100644 --- a/src/compiler/crystal/tools/doc/item.cr +++ b/src/compiler/crystal/tools/doc/item.cr @@ -7,3 +7,17 @@ module Crystal::Doc::Item @generator.summary(self) end end + +enum Crystal::Doc::HTMLOption + None + Highlight + All + + def highlight? : Bool + self >= Highlight + end + + def links? : Bool + self >= All + end +end diff --git a/src/compiler/crystal/tools/doc/macro.cr b/src/compiler/crystal/tools/doc/macro.cr index 07a667a69dcd..1ec25d14cad8 100644 --- a/src/compiler/crystal/tools/doc/macro.cr +++ b/src/compiler/crystal/tools/doc/macro.cr @@ -68,14 +68,14 @@ class Crystal::Doc::Macro end def args_to_s(io : IO) : Nil - args_to_html(io, html: false) + args_to_html(io, html: :none) end - def args_to_html - String.build { |io| args_to_html io } + def args_to_html(html : HTMLOption = :all) + String.build { |io| args_to_html io, html } end - def args_to_html(io : IO, html : Bool = true) : Nil + def args_to_html(io : IO, html : HTMLOption = :all) : Nil return unless has_args? printed = false @@ -104,14 +104,14 @@ class Crystal::Doc::Macro io << ')' end - def arg_to_html(arg : Arg, io, html = true) + def arg_to_html(arg : Arg, io, html : HTMLOption = :all) if arg.external_name != arg.name name = arg.external_name.presence || "_" if Symbol.needs_quotes? name - if html - HTML.escape name.inspect, io - else + if html.none? name.inspect io + else + HTML.escape name.inspect, io end else io << name @@ -125,7 +125,7 @@ class Crystal::Doc::Macro if default_value = arg.default_value io << " = " - if html + if html.highlight? io << Highlighter.highlight(default_value.to_s) else io << default_value diff --git a/src/compiler/crystal/tools/doc/method.cr b/src/compiler/crystal/tools/doc/method.cr index ccaac1c8feb1..d582c48968fe 100644 --- a/src/compiler/crystal/tools/doc/method.cr +++ b/src/compiler/crystal/tools/doc/method.cr @@ -211,14 +211,14 @@ class Crystal::Doc::Method end def args_to_s(io : IO) : Nil - args_to_html(io, html: false) + args_to_html(io, html: :none) end - def args_to_html - String.build { |io| args_to_html io } + def args_to_html(html : HTMLOption = :all) + String.build { |io| args_to_html io, html } end - def args_to_html(io : IO, html : Bool = true) : Nil + def args_to_html(io : IO, html : HTMLOption = :all) : Nil return_type = self.return_type return unless has_args? || return_type @@ -268,14 +268,14 @@ class Crystal::Doc::Method io end - def arg_to_html(arg : Arg, io, html = true) + def arg_to_html(arg : Arg, io, html : HTMLOption = :all) if arg.external_name != arg.name name = arg.external_name.presence || "_" if Symbol.needs_quotes? name - if html - HTML.escape name.inspect, io - else + if html.none? name.inspect io + else + HTML.escape name.inspect, io end else io << name @@ -295,7 +295,7 @@ class Crystal::Doc::Method if default_value = arg.default_value io << " = " - if html + if html.highlight? io << Highlighter.highlight(default_value.to_s) else io << default_value @@ -303,7 +303,7 @@ class Crystal::Doc::Method end end - def node_to_html(node, io, html = true) + def node_to_html(node, io, html : HTMLOption = :all) @type.node_to_html node, io, html: html end diff --git a/src/compiler/crystal/tools/doc/type.cr b/src/compiler/crystal/tools/doc/type.cr index ab4af44cb3f4..c32243db0a06 100644 --- a/src/compiler/crystal/tools/doc/type.cr +++ b/src/compiler/crystal/tools/doc/type.cr @@ -473,7 +473,7 @@ class Crystal::Doc::Type String.build { |io| node_to_html node, io } end - def node_to_html(node : Path, io, html = true) + def node_to_html(node : Path, io, html : HTMLOption = :all) match = lookup_path(node) if match # If the path is global, search a local path and @@ -493,7 +493,7 @@ class Crystal::Doc::Type end end - def node_to_html(node : Generic, io, html = true) + def node_to_html(node : Generic, io, html : HTMLOption = :all) node_to_html node.name, io, html: html io << '(' node.type_vars.join(io, ", ") do |type_var| @@ -502,7 +502,7 @@ class Crystal::Doc::Type io << ')' end - def node_to_html(node : ProcNotation, io, html = true) + def node_to_html(node : ProcNotation, io, html : HTMLOption = :all) if inputs = node.inputs inputs.join(io, ", ") do |input| node_to_html input, io, html: html @@ -514,7 +514,7 @@ class Crystal::Doc::Type end end - def node_to_html(node : Union, io, html = true) + def node_to_html(node : Union, io, html : HTMLOption = :all) # See if it's a nilable type if node.types.size == 2 # See if first type is Nil @@ -547,15 +547,15 @@ class Crystal::Doc::Type match && match.type == @generator.program.nil_type end - def node_to_html(node, io, html = true) - if html + def node_to_html(node, io, html : HTMLOption = :all) + if html.highlight? io << Highlighter.highlight(node.to_s) else io << node end end - def node_to_html(node : Underscore, io, html = true) + def node_to_html(node : Underscore, io, html : HTMLOption = :all) io << '_' end @@ -564,7 +564,7 @@ class Crystal::Doc::Type String.build { |io| type_to_html(type, io) } end - def type_to_html(type : Crystal::UnionType, io, text = nil, html = true) + def type_to_html(type : Crystal::UnionType, io, text = nil, html : HTMLOption = :all) has_type_splat = type.union_types.any? &.is_a?(TypeSplat) if !has_type_splat && type.union_types.size == 2 @@ -589,7 +589,7 @@ class Crystal::Doc::Type io << ')' if has_type_splat end - def type_to_html(type : Crystal::ProcInstanceType, io, text = nil, html = true) + def type_to_html(type : Crystal::ProcInstanceType, io, text = nil, html : HTMLOption = :all) type.arg_types.join(io, ", ") do |arg_type| type_to_html arg_type, io, html: html end @@ -598,7 +598,7 @@ class Crystal::Doc::Type type_to_html return_type, io, html: html unless return_type.void? end - def type_to_html(type : Crystal::TupleInstanceType, io, text = nil, html = true) + def type_to_html(type : Crystal::TupleInstanceType, io, text = nil, html : HTMLOption = :all) io << '{' type.tuple_types.join(io, ", ") do |tuple_type| type_to_html tuple_type, io, html: html @@ -606,7 +606,7 @@ class Crystal::Doc::Type io << '}' end - def type_to_html(type : Crystal::NamedTupleInstanceType, io, text = nil, html = true) + def type_to_html(type : Crystal::NamedTupleInstanceType, io, text = nil, html : HTMLOption = :all) io << '{' type.entries.join(io, ", ") do |entry| if Symbol.needs_quotes?(entry.name) @@ -620,12 +620,12 @@ class Crystal::Doc::Type io << '}' end - def type_to_html(type : Crystal::GenericInstanceType, io, text = nil, html = true) + def type_to_html(type : Crystal::GenericInstanceType, io, text = nil, html : HTMLOption = :all) has_link_in_type_vars = type.type_vars.any? { |(name, type_var)| type_has_link? type_var.as?(Var).try(&.type) || type_var } generic_type = @generator.type(type.generic_type) must_be_included = generic_type.must_be_included? - if must_be_included && html + if must_be_included && html.links? io << %() @@ -637,7 +637,7 @@ class Crystal::Doc::Type generic_type.full_name_without_type_vars(io) end - io << "" if must_be_included && html && has_link_in_type_vars + io << "" if must_be_included && html.links? && has_link_in_type_vars io << '(' type.type_vars.values.join(io, ", ") do |type_var| @@ -650,17 +650,17 @@ class Crystal::Doc::Type end io << ')' - io << "" if must_be_included && html && !has_link_in_type_vars + io << "" if must_be_included && html.links? && !has_link_in_type_vars end - def type_to_html(type : Crystal::VirtualType, io, text = nil, html = true) + def type_to_html(type : Crystal::VirtualType, io, text = nil, html : HTMLOption = :all) type_to_html type.base_type, io, text, html: html end - def type_to_html(type : Crystal::Type, io, text = nil, html = true) + def type_to_html(type : Crystal::Type, io, text = nil, html : HTMLOption = :all) type = @generator.type(type) if type.must_be_included? - if html + if html.links? io << %() @@ -670,7 +670,7 @@ class Crystal::Doc::Type else type.full_name(io) end - if html + if html.links? io << "" end else @@ -682,11 +682,11 @@ class Crystal::Doc::Type end end - def type_to_html(type : Type, io, text = nil, html = true) + def type_to_html(type : Type, io, text = nil, html : HTMLOption = :all) type_to_html type.type, io, text, html: html end - def type_to_html(type : ASTNode, io, text = nil, html = true) + def type_to_html(type : ASTNode, io, text = nil, html : HTMLOption = :all) type.to_s io end From aabdf28eb9f82545a4a827f38257bdf700e14f15 Mon Sep 17 00:00:00 2001 From: Oleh Prypin Date: Sat, 2 Jan 2021 15:38:23 +0100 Subject: [PATCH 7/7] No longer need the hack to strip HTML --- src/compiler/crystal/tools/doc/macro.cr | 2 +- src/compiler/crystal/tools/doc/method.cr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/crystal/tools/doc/macro.cr b/src/compiler/crystal/tools/doc/macro.cr index 1ec25d14cad8..1638be803645 100644 --- a/src/compiler/crystal/tools/doc/macro.cr +++ b/src/compiler/crystal/tools/doc/macro.cr @@ -33,7 +33,7 @@ class Crystal::Doc::Macro def id String.build do |io| - io << to_s.gsub(/<.+?>/, "").delete(' ') + io << to_s.delete(' ') io << "-macro" end end diff --git a/src/compiler/crystal/tools/doc/method.cr b/src/compiler/crystal/tools/doc/method.cr index d582c48968fe..8a428b34a291 100644 --- a/src/compiler/crystal/tools/doc/method.cr +++ b/src/compiler/crystal/tools/doc/method.cr @@ -184,7 +184,7 @@ class Crystal::Doc::Method def id String.build do |io| - io << to_s.gsub(/<.+?>/, "").delete(' ') + io << to_s.delete(' ') if @class_method io << "-class-method" else