diff --git a/spec/compiler/parser/to_s_spec.cr b/spec/compiler/parser/to_s_spec.cr index 35f6335a7af6..64eee3267288 100644 --- a/spec/compiler/parser/to_s_spec.cr +++ b/spec/compiler/parser/to_s_spec.cr @@ -29,4 +29,12 @@ describe "ASTNode#to_s" do it "puts parenthesis in call argument if it's a cast" do Parser.parse("foo(a as Int32)").to_s.should eq("foo((a as Int32))") end + + it "correctly convert a symbol that doesn't need qoutes" do + Parser.parse(%(:foo)).to_s.should eq(%(:foo)) + end + + it "correctly convert a symbol that needs qoutes" do + Parser.parse(%(:"{")).to_s.should eq(%(:"{")) + end end diff --git a/spec/std/symbol_spec.cr b/spec/std/symbol_spec.cr new file mode 100644 index 000000000000..121392959f76 --- /dev/null +++ b/spec/std/symbol_spec.cr @@ -0,0 +1,10 @@ +require "spec" + +describe Symbol do + it "inspects" do + :foo.inspect.should eq(%(:foo)) + :"{".inspect.should eq(%(:"{")) + :"hi there".inspect.should eq(%(:"hi there")) + # :かたな.inspect.should eq(%(:かたな)) + end +end diff --git a/src/compiler/crystal/syntax/to_s.cr b/src/compiler/crystal/syntax/to_s.cr index 06abb4c7ee7c..b6e3059169e8 100644 --- a/src/compiler/crystal/syntax/to_s.cr +++ b/src/compiler/crystal/syntax/to_s.cr @@ -40,15 +40,22 @@ module Crystal end def visit(node : CharLiteral) - @str << node.value.inspect + node.value.inspect(@str) end def visit(node : SymbolLiteral) - @str << ":" << node.value + @str << ':' + + value = node.value + if Symbol.needs_quotes?(value) + value.inspect(@str) + else + value.to_s(@str) + end end def visit(node : StringLiteral) - @str << node.value.inspect + node.value.inspect(@str) end def visit(node : StringInterpolation) diff --git a/src/symbol.cr b/src/symbol.cr index 7b74cdaca33b..318696894826 100644 --- a/src/symbol.cr +++ b/src/symbol.cr @@ -1,10 +1,29 @@ struct Symbol def inspect(io : IO) io << ":" - to_s io + + value = to_s + if Symbol.needs_quotes?(value) + value.inspect(io) + else + value.to_s(io) + end end def to_s(io : IO) io << to_s end + + # Determines if a string needs to be quoted to be used for a symbol. + def self.needs_quotes?(string) + string.each_char do |char| + case char + when '0'..'9', 'A'..'Z', 'a'..'z', '_' + # Nothing + else + return true + end + end + false + end end