From 5dbfdb4a1d1a37f3045ae61de4f85db2ff58fbc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Thu, 22 Jun 2023 20:48:53 +0200 Subject: [PATCH 1/5] Refactor symbol quoting into `Symbol.quote_for_named_argument` --- src/compiler/crystal/macros/methods.cr | 6 +----- src/compiler/crystal/semantic/call_error.cr | 12 ++---------- src/compiler/crystal/syntax/to_s.cr | 12 ++---------- src/compiler/crystal/tools/doc/type.cr | 12 ++---------- src/compiler/crystal/types.cr | 6 +----- src/named_tuple.cr | 14 ++------------ src/symbol.cr | 20 ++++++++++++++++++++ 7 files changed, 30 insertions(+), 52 deletions(-) diff --git a/src/compiler/crystal/macros/methods.cr b/src/compiler/crystal/macros/methods.cr index 74021a7ce825..36bd79fa64e9 100644 --- a/src/compiler/crystal/macros/methods.cr +++ b/src/compiler/crystal/macros/methods.cr @@ -1048,11 +1048,7 @@ module Crystal private def to_double_splat(trailing_string = "") MacroId.new(entries.join(", ") do |entry| - if Symbol.needs_quotes_for_named_argument?(entry.key) - "#{entry.key.inspect}: #{entry.value}" - else - "#{entry.key}: #{entry.value}" - end + "#{Symbol.quote_for_named_argument(entry.key)}: #{entry.value}" end + trailing_string) end end diff --git a/src/compiler/crystal/semantic/call_error.cr b/src/compiler/crystal/semantic/call_error.cr index 89136be3dc16..a0528e83c44f 100644 --- a/src/compiler/crystal/semantic/call_error.cr +++ b/src/compiler/crystal/semantic/call_error.cr @@ -1032,11 +1032,7 @@ class Crystal::Call next if arg_type.entries.empty? io << ", " unless first arg_type.entries.join(io, ", ") do |entry| - if Symbol.needs_quotes_for_named_argument?(entry.name) - entry.name.inspect(io) - else - io << entry.name - end + Symbol.quote_for_named_argument(io, entry.name) io << ": " << entry.type end else @@ -1049,11 +1045,7 @@ class Crystal::Call if named_args = @named_args io << ", " unless first named_args.join(io, ", ") do |named_arg| - if Symbol.needs_quotes_for_named_argument?(named_arg.name) - named_arg.name.inspect(io) - else - io << named_arg.name - end + Symbol.quote_for_named_argument(io, named_arg.name) io << ": " << named_arg.value.type end end diff --git a/src/compiler/crystal/syntax/to_s.cr b/src/compiler/crystal/syntax/to_s.cr index cdd0780bdf70..006e73778a45 100644 --- a/src/compiler/crystal/syntax/to_s.cr +++ b/src/compiler/crystal/syntax/to_s.cr @@ -885,11 +885,7 @@ module Crystal end def visit_named_arg_name(name) - if Symbol.needs_quotes_for_named_argument?(name) - name.inspect(@str) - else - @str << name - end + Symbol.quote_for_named_argument(@str, name) end def visit(node : Underscore) @@ -1123,11 +1119,7 @@ module Crystal else @str << node.name @str << " = " - if Symbol.needs_quotes_for_named_argument?(node.real_name) - node.real_name.inspect(@str) - else - @str << node.real_name - end + Symbol.quote_for_named_argument(@str, node.real_name) end if node.args.size > 0 @str << '(' diff --git a/src/compiler/crystal/tools/doc/type.cr b/src/compiler/crystal/tools/doc/type.cr index d8748ef898e3..619c32cd1fcd 100644 --- a/src/compiler/crystal/tools/doc/type.cr +++ b/src/compiler/crystal/tools/doc/type.cr @@ -517,11 +517,7 @@ class Crystal::Doc::Type if (named_args = node.named_args) && !named_args.empty? io << ", " unless node.type_vars.empty? named_args.join(io, ", ") do |entry| - if Symbol.needs_quotes_for_named_argument?(entry.name) - entry.name.inspect(io) - else - io << entry.name - end + Symbol.quote_for_named_argument(io, entry.name) io << ": " node_to_html entry.value, io, html: html end @@ -636,11 +632,7 @@ class Crystal::Doc::Type def type_to_html(type : Crystal::NamedTupleInstanceType, io, text = nil, html : HTMLOption = :all) io << '{' type.entries.join(io, ", ") do |entry| - if Symbol.needs_quotes_for_named_argument?(entry.name) - entry.name.inspect(io) - else - io << entry.name - end + Symbol.quote_for_named_argument(io, entry.name) io << ": " type_to_html entry.type, io, html: html end diff --git a/src/compiler/crystal/types.cr b/src/compiler/crystal/types.cr index d4b73df92ec4..7d4bc9795a7f 100644 --- a/src/compiler/crystal/types.cr +++ b/src/compiler/crystal/types.cr @@ -2628,11 +2628,7 @@ module Crystal def to_s_with_options(io : IO, skip_union_parens : Bool = false, generic_args : Bool = true, codegen : Bool = false) : Nil io << "NamedTuple(" @entries.join(io, ", ") do |entry| - if Symbol.needs_quotes_for_named_argument?(entry.name) - entry.name.inspect(io) - else - io << entry.name - end + Symbol.quote_for_named_argument(io, entry.name) io << ": " entry_type = entry.type entry_type = entry_type.devirtualize unless codegen diff --git a/src/named_tuple.cr b/src/named_tuple.cr index 3bf8abd38938..7cceb568a260 100644 --- a/src/named_tuple.cr +++ b/src/named_tuple.cr @@ -449,12 +449,7 @@ struct NamedTuple {% if i > 0 %} io << ", " {% end %} - key = {{key.stringify}} - if Symbol.needs_quotes_for_named_argument?(key) - key.inspect(io) - else - io << key - end + Symbol.quote_for_named_argument io, {{key.stringify}} io << ": " self[{{key.symbolize}}].inspect(io) {% end %} @@ -468,12 +463,7 @@ struct NamedTuple pp.comma {% end %} pp.group do - key = {{key.stringify}} - if Symbol.needs_quotes_for_named_argument?(key) - pp.text key.inspect - else - pp.text key - end + pp.text Symbol.quote_for_named_argument({{key.stringify}}) pp.text ": " pp.nest do pp.breakable "" diff --git a/src/symbol.cr b/src/symbol.cr index a3d6ffd8d4fe..88b9d0db904e 100644 --- a/src/symbol.cr +++ b/src/symbol.cr @@ -99,6 +99,26 @@ struct Symbol end end + # :nodoc: + # Appends *string* to *io* and quotes it if necessary. + def self.quote_for_named_argument(io : IO, string : String) : Nil + if needs_quotes_for_named_argument?(string) + string.inspect(io) + else + io << string + end + end + + # :nodoc: + # Returns *string* and quotes it if necessary. + def self.quote_for_named_argument(string : String) : String + if needs_quotes_for_named_argument?(string) + string.inspect + else + string + end + end + def clone self end From 31ea05d47db6112b002d534c0e215e0f5e6921ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Thu, 22 Jun 2023 20:56:28 +0200 Subject: [PATCH 2/5] Use `.quote_for_named_argument` in doc generator --- src/compiler/crystal/tools/doc/macro.cr | 11 ++++------- src/compiler/crystal/tools/doc/method.cr | 11 ++++------- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/src/compiler/crystal/tools/doc/macro.cr b/src/compiler/crystal/tools/doc/macro.cr index 2dffca65b94a..bbe89b8f3ce2 100644 --- a/src/compiler/crystal/tools/doc/macro.cr +++ b/src/compiler/crystal/tools/doc/macro.cr @@ -107,14 +107,11 @@ class Crystal::Doc::Macro def arg_to_html(arg : Arg, io, html : HTMLOption = :all) if arg.external_name != arg.name if name = arg.external_name.presence - if Symbol.needs_quotes_for_named_argument? name - if html.none? - name.inspect io - else - HTML.escape name.inspect, io - end - else + name = Symbol.quote_for_named_argument(name) + if html.none? io << name + else + HTML.escape name end else io << "_" diff --git a/src/compiler/crystal/tools/doc/method.cr b/src/compiler/crystal/tools/doc/method.cr index 10b223a81d76..05e70044553a 100644 --- a/src/compiler/crystal/tools/doc/method.cr +++ b/src/compiler/crystal/tools/doc/method.cr @@ -272,14 +272,11 @@ class Crystal::Doc::Method def arg_to_html(arg : Arg, io, html : HTMLOption = :all) if arg.external_name != arg.name if name = arg.external_name.presence - if Symbol.needs_quotes_for_named_argument? name - if html.none? - name.inspect io - else - HTML.escape name.inspect, io - end - else + name = Symbol.quote_for_named_argument(name) + if html.none? io << name + else + HTML.escape name end else io << "_" From 4a44cdaa7e64191ee1a7c20e89c333684db74ab9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Thu, 22 Jun 2023 20:57:19 +0200 Subject: [PATCH 3/5] Deprecate `Symbol.needs_quotes_for_named_argument?` --- src/symbol.cr | 1 + 1 file changed, 1 insertion(+) diff --git a/src/symbol.cr b/src/symbol.cr index 88b9d0db904e..1f57ddc7f574 100644 --- a/src/symbol.cr +++ b/src/symbol.cr @@ -78,6 +78,7 @@ struct Symbol # :nodoc: # Determines if a string needs to be quoted to be used for an external # parameter name or a named argument's key. + @[Deprecated("Use `.quite_for_named_argument` instead")] def self.needs_quotes_for_named_argument?(string) : Bool case string when "", "_" From 5e387fa25a233f2d50af69c2ca0cc451f6f613c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Thu, 22 Jun 2023 22:46:31 +0200 Subject: [PATCH 4/5] fixup! Use `.quote_for_named_argument` in doc generator --- 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 bbe89b8f3ce2..49b9c30795bc 100644 --- a/src/compiler/crystal/tools/doc/macro.cr +++ b/src/compiler/crystal/tools/doc/macro.cr @@ -111,7 +111,7 @@ class Crystal::Doc::Macro if html.none? io << name else - HTML.escape name + HTML.escape name, io end else io << "_" diff --git a/src/compiler/crystal/tools/doc/method.cr b/src/compiler/crystal/tools/doc/method.cr index 05e70044553a..069deb48ee61 100644 --- a/src/compiler/crystal/tools/doc/method.cr +++ b/src/compiler/crystal/tools/doc/method.cr @@ -276,7 +276,7 @@ class Crystal::Doc::Method if html.none? io << name else - HTML.escape name + HTML.escape name, io end else io << "_" From 25acb327b51315d9189cedb576b5b377eaf400dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Fri, 23 Jun 2023 14:23:50 +0200 Subject: [PATCH 5/5] Remove deprecation --- src/symbol.cr | 1 - 1 file changed, 1 deletion(-) diff --git a/src/symbol.cr b/src/symbol.cr index 1f57ddc7f574..88b9d0db904e 100644 --- a/src/symbol.cr +++ b/src/symbol.cr @@ -78,7 +78,6 @@ struct Symbol # :nodoc: # Determines if a string needs to be quoted to be used for an external # parameter name or a named argument's key. - @[Deprecated("Use `.quite_for_named_argument` instead")] def self.needs_quotes_for_named_argument?(string) : Bool case string when "", "_"