diff --git a/components/prism-crystal.js b/components/prism-crystal.js index cf877587d0..c2c0c53a9a 100644 --- a/components/prism-crystal.js +++ b/components/prism-crystal.js @@ -1,51 +1,57 @@ (function (Prism) { Prism.languages.crystal = Prism.languages.extend('ruby', { - keyword: [ - /\b(?:__DIR__|__END_LINE__|__FILE__|__LINE__|abstract|alias|as|asm|begin|break|case|class|def|do|else|elsif|end|ensure|enum|extend|for|fun|if|include|instance_sizeof|lib|macro|module|next|of|out|pointerof|private|protected|require|rescue|return|select|self|sizeof|struct|super|then|type|typeof|uninitialized|union|unless|until|when|while|with|yield)\b/, + 'keyword': [ + /\b(?:__DIR__|__END_LINE__|__FILE__|__LINE__|abstract|alias|annotation|as|asm|begin|break|case|class|def|do|else|elsif|end|ensure|enum|extend|for|fun|if|ifdef|include|instance_sizeof|lib|macro|module|next|of|out|pointerof|private|protected|ptr|require|rescue|return|select|self|sizeof|struct|super|then|type|typeof|undef|uninitialized|union|unless|until|when|while|with|yield)\b/, { pattern: /(\.\s*)(?:is_a|responds_to)\?/, lookbehind: true } ], - - number: /\b(?:0b[01_]*[01]|0o[0-7_]*[0-7]|0x[\da-fA-F_]*[\da-fA-F]|(?:\d(?:[\d_]*\d)?)(?:\.[\d_]*\d)?(?:[eE][+-]?[\d_]*\d)?)(?:_(?:[uif](?:8|16|32|64))?)?\b/ + 'number': /\b(?:0b[01_]*[01]|0o[0-7_]*[0-7]|0x[\da-fA-F_]*[\da-fA-F]|(?:\d(?:[\d_]*\d)?)(?:\.[\d_]*\d)?(?:[eE][+-]?[\d_]*\d)?)(?:_(?:[uif](?:8|16|32|64))?)?\b/, + 'operator': [ + /->/, + Prism.languages.ruby.operator, + ], + 'punctuation': /[(){}[\].,;\\]/, }); Prism.languages.insertBefore('crystal', 'string-literal', { - attribute: { - pattern: /@\[.+?\]/, - alias: 'attr-name', + 'attribute': { + pattern: /@\[.*?\]/, inside: { - delimiter: { + 'delimiter': { pattern: /^@\[|\]$/, - alias: 'tag' + alias: 'punctuation' + }, + 'attribute': { + pattern: /^(\s*)\w+/, + lookbehind: true, + alias: 'class-name' + }, + 'args': { + pattern: /\S(?:[\s\S]*\S)?/, + inside: Prism.languages.crystal }, - rest: Prism.languages.crystal } }, - - expansion: [ - { - pattern: /\{\{.+?\}\}/, - inside: { - delimiter: { - pattern: /^\{\{|\}\}$/, - alias: 'tag' - }, - rest: Prism.languages.crystal - } - }, - { - pattern: /\{%.+?%\}/, - inside: { - delimiter: { - pattern: /^\{%|%\}$/, - alias: 'tag' - }, - rest: Prism.languages.crystal + 'expansion': { + pattern: /\{(?:\{.*?\}|%.*?%)\}/, + inside: { + 'content': { + pattern: /^(\{.)[\s\S]+(?=.\}$)/, + lookbehind: true, + inside: Prism.languages.crystal + }, + 'delimiter': { + pattern: /^\{[\{%]|[\}%]\}$/, + alias: 'operator' } } - ] + }, + 'char': { + pattern: /'(?:[^\\\r\n]{1,2}|\\(?:.|u(?:[A-Fa-f0-9]{1,4}|\{[A-Fa-f0-9]{1,6}\})))'/, + greedy: true + } }); }(Prism)); diff --git a/components/prism-crystal.min.js b/components/prism-crystal.min.js index aca3593c69..145ced2ea8 100644 --- a/components/prism-crystal.min.js +++ b/components/prism-crystal.min.js @@ -1 +1 @@ -!function(e){e.languages.crystal=e.languages.extend("ruby",{keyword:[/\b(?:__DIR__|__END_LINE__|__FILE__|__LINE__|abstract|alias|as|asm|begin|break|case|class|def|do|else|elsif|end|ensure|enum|extend|for|fun|if|include|instance_sizeof|lib|macro|module|next|of|out|pointerof|private|protected|require|rescue|return|select|self|sizeof|struct|super|then|type|typeof|uninitialized|union|unless|until|when|while|with|yield)\b/,{pattern:/(\.\s*)(?:is_a|responds_to)\?/,lookbehind:!0}],number:/\b(?:0b[01_]*[01]|0o[0-7_]*[0-7]|0x[\da-fA-F_]*[\da-fA-F]|(?:\d(?:[\d_]*\d)?)(?:\.[\d_]*\d)?(?:[eE][+-]?[\d_]*\d)?)(?:_(?:[uif](?:8|16|32|64))?)?\b/}),e.languages.insertBefore("crystal","string-literal",{attribute:{pattern:/@\[.+?\]/,alias:"attr-name",inside:{delimiter:{pattern:/^@\[|\]$/,alias:"tag"},rest:e.languages.crystal}},expansion:[{pattern:/\{\{.+?\}\}/,inside:{delimiter:{pattern:/^\{\{|\}\}$/,alias:"tag"},rest:e.languages.crystal}},{pattern:/\{%.+?%\}/,inside:{delimiter:{pattern:/^\{%|%\}$/,alias:"tag"},rest:e.languages.crystal}}]})}(Prism); \ No newline at end of file +!function(e){e.languages.crystal=e.languages.extend("ruby",{keyword:[/\b(?:__DIR__|__END_LINE__|__FILE__|__LINE__|abstract|alias|annotation|as|asm|begin|break|case|class|def|do|else|elsif|end|ensure|enum|extend|for|fun|if|ifdef|include|instance_sizeof|lib|macro|module|next|of|out|pointerof|private|protected|ptr|require|rescue|return|select|self|sizeof|struct|super|then|type|typeof|undef|uninitialized|union|unless|until|when|while|with|yield)\b/,{pattern:/(\.\s*)(?:is_a|responds_to)\?/,lookbehind:!0}],number:/\b(?:0b[01_]*[01]|0o[0-7_]*[0-7]|0x[\da-fA-F_]*[\da-fA-F]|(?:\d(?:[\d_]*\d)?)(?:\.[\d_]*\d)?(?:[eE][+-]?[\d_]*\d)?)(?:_(?:[uif](?:8|16|32|64))?)?\b/,operator:[/->/,e.languages.ruby.operator],punctuation:/[(){}[\].,;\\]/}),e.languages.insertBefore("crystal","string-literal",{attribute:{pattern:/@\[.*?\]/,inside:{delimiter:{pattern:/^@\[|\]$/,alias:"punctuation"},attribute:{pattern:/^(\s*)\w+/,lookbehind:!0,alias:"class-name"},args:{pattern:/\S(?:[\s\S]*\S)?/,inside:e.languages.crystal}}},expansion:{pattern:/\{(?:\{.*?\}|%.*?%)\}/,inside:{content:{pattern:/^(\{.)[\s\S]+(?=.\}$)/,lookbehind:!0,inside:e.languages.crystal},delimiter:{pattern:/^\{[\{%]|[\}%]\}$/,alias:"operator"}}},char:{pattern:/'(?:[^\\\r\n]{1,2}|\\(?:.|u(?:[A-Fa-f0-9]{1,4}|\{[A-Fa-f0-9]{1,6}\})))'/,greedy:!0}})}(Prism); \ No newline at end of file diff --git a/tests/languages/crystal/attribute_feature.test b/tests/languages/crystal/attribute_feature.test index 61b486882b..726049b028 100644 --- a/tests/languages/crystal/attribute_feature.test +++ b/tests/languages/crystal/attribute_feature.test @@ -8,47 +8,53 @@ [ ["attribute", [ ["delimiter", "@["], - "AlwaysInline", + ["attribute", "AlwaysInline"], ["delimiter", "]"] ]], ["attribute", [ ["delimiter", "@["], - "CallConvention", - ["punctuation", "("], - ["string-literal", [ - ["string", "\"X86_StdCall\""] + ["attribute", "CallConvention"], + ["args", [ + ["punctuation", "("], + ["string-literal", [ + ["string", "\"X86_StdCall\""] + ]], + ["punctuation", ")"] ]], - ["punctuation", ")"], ["delimiter", "]"] ]], ["attribute", [ ["delimiter", "@["], - "MyAnnotation", - ["punctuation", "("], - ["symbol", "key"], - ["operator", ":"], - ["string-literal", [ - ["string", "\"value\""] + ["attribute", "MyAnnotation"], + ["args", [ + ["punctuation", "("], + ["symbol", "key"], + ["operator", ":"], + ["string-literal", [ + ["string", "\"value\""] + ]], + ["punctuation", ","], + ["symbol", "value"], + ["operator", ":"], + ["number", "123"], + ["punctuation", ")"] ]], - ["punctuation", ","], - ["symbol", "value"], - ["operator", ":"], - ["number", "123"], - ["punctuation", ")"], ["delimiter", "]"] ]], ["attribute", [ ["delimiter", "@["], - "MyAnnotation", - ["punctuation", "("], - ["string-literal", [ - ["string", "\"foo\""] + ["attribute", "MyAnnotation"], + ["args", [ + ["punctuation", "("], + ["string-literal", [ + ["string", "\"foo\""] + ]], + ["punctuation", ","], + ["number", "123"], + ["punctuation", ","], + ["boolean", "false"], + ["punctuation", ")"] ]], - ["punctuation", ","], - ["number", "123"], - ["punctuation", ","], - ["boolean", "false"], - ["punctuation", ")"], ["delimiter", "]"] ]] ] diff --git a/tests/languages/crystal/char_feature.test b/tests/languages/crystal/char_feature.test new file mode 100644 index 0000000000..6734edc97b --- /dev/null +++ b/tests/languages/crystal/char_feature.test @@ -0,0 +1,41 @@ +'a' +'z' +'0' +'_' +'あ' +'\'' # single quote +'\\' # backslash +'\a' # alert +'\b' # backspace +'\e' # escape +'\f' # form feed +'\n' # newline +'\r' # carriage return +'\t' # tab +'\v' # vertical tab +'\0' # null character +'\uFFFF' # hexadecimal unicode character +'\u{10FFFF}' # hexadecimal unicode character + +---------------------------------------------------- + +[ + ["char", "'a'"], + ["char", "'z'"], + ["char", "'0'"], + ["char", "'_'"], + ["char", "'あ'"], + ["char", "'\\''"], ["comment", "# single quote"], + ["char", "'\\\\'"], ["comment", "# backslash"], + ["char", "'\\a'"], ["comment", "# alert"], + ["char", "'\\b'"], ["comment", "# backspace"], + ["char", "'\\e'"], ["comment", "# escape"], + ["char", "'\\f'"], ["comment", "# form feed"], + ["char", "'\\n'"], ["comment", "# newline"], + ["char", "'\\r'"], ["comment", "# carriage return"], + ["char", "'\\t'"], ["comment", "# tab"], + ["char", "'\\v'"], ["comment", "# vertical tab"], + ["char", "'\\0'"], ["comment", "# null character"], + ["char", "'\\uFFFF'"], ["comment", "# hexadecimal unicode character"], + ["char", "'\\u{10FFFF}'"], ["comment", "# hexadecimal unicode character"] +] diff --git a/tests/languages/crystal/expansion_feature.test b/tests/languages/crystal/expansion_feature.test index b40bd1f51f..b11bcc4ab1 100644 --- a/tests/languages/crystal/expansion_feature.test +++ b/tests/languages/crystal/expansion_feature.test @@ -8,26 +8,34 @@ [ ["expansion", [ ["delimiter", "{{"], - ["number", "1_u32"], + ["content", [ + ["number", "1_u32"] + ]], ["delimiter", "}}"] ]], ["expansion", [ ["delimiter", "{%"], - ["number", "2_u32"], + ["content", [ + ["number", "2_u32"] + ]], ["delimiter", "%}"] ]], ["expansion", [ ["delimiter", "{{"], - ["punctuation", "{"], - ["number", "3_u32"], - ["punctuation", "}"], + ["content", [ + ["punctuation", "{"], + ["number", "3_u32"], + ["punctuation", "}"] + ]], ["delimiter", "}}"] ]], ["expansion", [ ["delimiter", "{%"], - ["operator", "%"], - ["number", "4_u32"], - ["operator", "%"], + ["content", [ + ["operator", "%"], + ["number", "4_u32"], + ["operator", "%"] + ]], ["delimiter", "%}"] ]] ] diff --git a/tests/languages/crystal/keyword_feature.test b/tests/languages/crystal/keyword_feature.test index d97c9d6063..5b61e97ae3 100644 --- a/tests/languages/crystal/keyword_feature.test +++ b/tests/languages/crystal/keyword_feature.test @@ -2,6 +2,7 @@ .responds_to? abstract alias +annotation; as asm begin @@ -19,6 +20,7 @@ extend for fun if +ifdef include instance_sizeof lib @@ -30,6 +32,7 @@ out pointerof private protected +ptr require rescue return @@ -41,6 +44,7 @@ super then type typeof +undef uninitialized union unless @@ -62,6 +66,7 @@ __LINE__ ["punctuation", "."], ["keyword", "responds_to?"], ["keyword", "abstract"], ["keyword", "alias"], + ["keyword", "annotation"], ["punctuation", ";"], ["keyword", "as"], ["keyword", "asm"], ["keyword", "begin"], @@ -79,6 +84,7 @@ __LINE__ ["keyword", "for"], ["keyword", "fun"], ["keyword", "if"], + ["keyword", "ifdef"], ["keyword", "include"], ["keyword", "instance_sizeof"], ["keyword", "lib"], @@ -90,6 +96,7 @@ __LINE__ ["keyword", "pointerof"], ["keyword", "private"], ["keyword", "protected"], + ["keyword", "ptr"], ["keyword", "require"], ["keyword", "rescue"], ["keyword", "return"], @@ -101,6 +108,7 @@ __LINE__ ["keyword", "then"], ["keyword", "type"], ["keyword", "typeof"], + ["keyword", "undef"], ["keyword", "uninitialized"], ["keyword", "union"], ["keyword", "unless"], diff --git a/tests/languages/crystal/operator_feature.test b/tests/languages/crystal/operator_feature.test new file mode 100644 index 0000000000..43c7205933 --- /dev/null +++ b/tests/languages/crystal/operator_feature.test @@ -0,0 +1,82 @@ ++ - * / % ** ++= -= *= /= %= **= + +== != < > <= >= <=> === +!~ =~ += +& | ^ ~ << >> +&= |= ^= <<= >>= +&& || ! +&&= ||= + +=> +-> + +&. + +? : +.. ... + +and or not + +---------------------------------------------------- + +[ + ["operator", "+"], + ["operator", "-"], + ["operator", "*"], + ["operator", "/"], + ["operator", "%"], + ["operator", "**"], + + ["operator", "+="], + ["operator", "-="], + ["operator", "*="], + ["operator", "/="], + ["operator", "%="], + ["operator", "**="], + + ["operator", "=="], + ["operator", "!="], + ["operator", "<"], + ["operator", ">"], + ["operator", "<="], + ["operator", ">="], + ["operator", "<=>"], + ["operator", "==="], + + ["operator", "!~"], + ["operator", "=~"], + + ["operator", "="], + + ["operator", "&"], + ["operator", "|"], + ["operator", "^"], + ["operator", "~"], + ["operator", "<<"], + ["operator", ">>"], + + ["operator", "&="], + ["operator", "|="], + ["operator", "^="], + ["operator", "<<="], + ["operator", ">>="], + + ["operator", "&&"], + ["operator", "||"], + ["operator", "!"], + + ["operator", "&&="], + ["operator", "||="], + + ["operator", "=>"], + ["operator", "->"], + + ["operator", "&."], + + ["operator", "?"], ["operator", ":"], + ["operator", ".."], ["operator", "..."], + + "\r\n\r\nand or not" +] diff --git a/tests/languages/crystal/punctuation_feature.test b/tests/languages/crystal/punctuation_feature.test new file mode 100644 index 0000000000..affcf8f11b --- /dev/null +++ b/tests/languages/crystal/punctuation_feature.test @@ -0,0 +1,20 @@ +( ) [ ] { } +, . +:: \ + +---------------------------------------------------- + +[ + ["punctuation", "("], + ["punctuation", ")"], + ["punctuation", "["], + ["punctuation", "]"], + ["punctuation", "{"], + ["punctuation", "}"], + + ["punctuation", ","], + ["punctuation", "."], + + ["double-colon", "::"], + ["punctuation", "\\"] +] diff --git a/tests/languages/crystal/regex_feature.test b/tests/languages/crystal/regex_feature.test new file mode 100644 index 0000000000..7f075142ee --- /dev/null +++ b/tests/languages/crystal/regex_feature.test @@ -0,0 +1,184 @@ +/foo|bar/ +/h(e+)llo/ +/\d+/ +/あ/ + +/\// # slash +/\\/ # backslash +/\b/ # backspace +/\e/ # escape +/\f/ # form feed +/\n/ # newline +/\r/ # carriage return +/\t/ # tab +/\v/ # vertical tab +/\NNN/ # octal ASCII character +/\xNN/ # hexadecimal ASCII character +/\x{FFFF}/ # hexadecimal unicode character +/\x{10FFFF}/ # hexadecimal unicode character + +/foo/i.match("FOO") # => # +/foo/m.match("bar\nfoo") # => # +/foo /x.match("foo") # => # +/foo /imx.match("bar\nFOO") # => # + +%r((/)) # => /(\/)/ +%r[[/]] # => /[\/]/ +%r{{/}} # => /{\/}/ +%r<> # => /<\/>/ +%r|/| # => /\// + +---------------------------------------------------- + +[ + ["regex-literal", [ + ["regex", "/foo|bar/"] + ]], + ["regex-literal", [ + ["regex", "/h(e+)llo/"] + ]], + ["regex-literal", [ + ["regex", "/\\d+/"] + ]], + ["regex-literal", [ + ["regex", "/あ/"] + ]], + + ["regex-literal", [ + ["regex", "/\\//"] + ]], + ["comment", "# slash"], + + ["regex-literal", [ + ["regex", "/\\\\/"] + ]], + ["comment", "# backslash"], + + ["regex-literal", [ + ["regex", "/\\b/"] + ]], + ["comment", "# backspace"], + + ["regex-literal", [ + ["regex", "/\\e/"] + ]], + ["comment", "# escape"], + + ["regex-literal", [ + ["regex", "/\\f/"] + ]], + ["comment", "# form feed"], + + ["regex-literal", [ + ["regex", "/\\n/"] + ]], + ["comment", "# newline"], + + ["regex-literal", [ + ["regex", "/\\r/"] + ]], + ["comment", "# carriage return"], + + ["regex-literal", [ + ["regex", "/\\t/"] + ]], + ["comment", "# tab"], + + ["regex-literal", [ + ["regex", "/\\v/"] + ]], + ["comment", "# vertical tab"], + + ["regex-literal", [ + ["regex", "/\\NNN/"] + ]], + ["comment", "# octal ASCII character"], + + ["regex-literal", [ + ["regex", "/\\xNN/"] + ]], + ["comment", "# hexadecimal ASCII character"], + + ["regex-literal", [ + ["regex", "/\\x{FFFF}/"] + ]], + ["comment", "# hexadecimal unicode character"], + + ["regex-literal", [ + ["regex", "/\\x{10FFFF}/"] + ]], + ["comment", "# hexadecimal unicode character"], + + ["regex-literal", [ + ["regex", "/foo/i"] + ]], + ["punctuation", "."], + "match", + ["punctuation", "("], + ["string-literal", [ + ["string", "\"FOO\""] + ]], + ["punctuation", ")"], + ["comment", "# => #"], + + ["regex-literal", [ + ["regex", "/foo/m"] + ]], + ["punctuation", "."], + "match", + ["punctuation", "("], + ["string-literal", [ + ["string", "\"bar\\nfoo\""] + ]], + ["punctuation", ")"], + ["comment", "# => #"], + + ["regex-literal", [ + ["regex", "/foo /x"] + ]], + ["punctuation", "."], + "match", + ["punctuation", "("], + ["string-literal", [ + ["string", "\"foo\""] + ]], + ["punctuation", ")"], + ["comment", "# => #"], + + ["regex-literal", [ + ["regex", "/foo /imx"] + ]], + ["punctuation", "."], + "match", + ["punctuation", "("], + ["string-literal", [ + ["string", "\"bar\\nFOO\""] + ]], + ["punctuation", ")"], + ["comment", "# => #"], + + ["regex-literal", [ + ["regex", "%r((/))"] + ]], + ["comment", "# => /(\\/)/"], + + ["regex-literal", [ + ["regex", "%r[[/]]"] + ]], + ["comment", "# => /[\\/]/"], + + ["regex-literal", [ + ["regex", "%r{{/}}"] + ]], + ["comment", "# => /{\\/}/"], + + ["regex-literal", [ + ["regex", "%r<>"] + ]], + ["comment", "# => /<\\/>/"], + + ["regex-literal", [ + ["regex", "%r|/|"] + ]], + ["comment", "# => /\\//"] +] diff --git a/tests/languages/crystal/string_feature.test b/tests/languages/crystal/string_feature.test new file mode 100644 index 0000000000..04a8ebded6 --- /dev/null +++ b/tests/languages/crystal/string_feature.test @@ -0,0 +1,321 @@ +"hello world" + +"\"" # double quote +"\\" # backslash +"\#" # hash character (to escape interpolation) +"\a" # alert +"\b" # backspace +"\e" # escape +"\f" # form feed +"\n" # newline +"\r" # carriage return +"\t" # tab +"\v" # vertical tab +"\377" # octal ASCII character +"\xFF" # hexadecimal ASCII character +"\uFFFF" # hexadecimal unicode character +"\u{0}".."\u{10FFFF}" # hexadecimal unicode character + +"\101" # => "A" +"\123" # => "S" +"\12" # => "\n" +"\1" # string with one character with code point 1 + +"\u{48 45 4C 4C 4F}" # => "HELLO" + +"sum: #{a} + #{b} = #{a + b}" + +"\#{a + b}" # => "#{a + b}" +%q(#{a + b}) # => "#{a + b}" + +%(hello ("world")) # => "hello (\"world\")" +%[hello ["world"]] # => "hello [\"world\"]" +%{hello {"world"}} # => "hello {\"world\"}" +%> # => "hello <\"world\">" +%|hello "world"| # => "hello \"world\"" + +name = "world" +%q(hello \n #{name}) # => "hello \\n \#{name}" +%Q(hello \n #{name}) # => "hello \n world" + +%w(foo bar baz) # => ["foo", "bar", "baz"] +%w(foo\nbar baz) # => ["foo\\nbar", "baz"] +%w(foo(bar) baz) # => ["foo(bar)", "baz"] + +%w(foo\ bar baz) # => ["foo bar", "baz"] + +"hello " \ +"world, " \ +"no newlines" # same as "hello world, no newlines" + +"hello \ + world, \ + no newlines" # same as "hello world, no newlines" + +<<-XML + + + +XML + +---------------------------------------------------- + +[ + ["string-literal", [ + ["string", "\"hello world\""] + ]], + + ["string-literal", [ + ["string", "\"\\\"\""] + ]], + ["comment", "# double quote"], + + ["string-literal", [ + ["string", "\"\\\\\""] + ]], + ["comment", "# backslash"], + + ["string-literal", [ + ["string", "\"\\#\""] + ]], + ["comment", "# hash character (to escape interpolation)"], + + ["string-literal", [ + ["string", "\"\\a\""] + ]], + ["comment", "# alert"], + + ["string-literal", [ + ["string", "\"\\b\""] + ]], + ["comment", "# backspace"], + + ["string-literal", [ + ["string", "\"\\e\""] + ]], + ["comment", "# escape"], + + ["string-literal", [ + ["string", "\"\\f\""] + ]], + ["comment", "# form feed"], + + ["string-literal", [ + ["string", "\"\\n\""] + ]], + ["comment", "# newline"], + + ["string-literal", [ + ["string", "\"\\r\""] + ]], + ["comment", "# carriage return"], + + ["string-literal", [ + ["string", "\"\\t\""] + ]], + ["comment", "# tab"], + + ["string-literal", [ + ["string", "\"\\v\""] + ]], + ["comment", "# vertical tab"], + + ["string-literal", [ + ["string", "\"\\377\""] + ]], + ["comment", "# octal ASCII character"], + + ["string-literal", [ + ["string", "\"\\xFF\""] + ]], + ["comment", "# hexadecimal ASCII character"], + + ["string-literal", [ + ["string", "\"\\uFFFF\""] + ]], + ["comment", "# hexadecimal unicode character"], + + ["string-literal", [ + ["string", "\"\\u{0}\""] + ]], + ["operator", ".."], + ["string-literal", [ + ["string", "\"\\u{10FFFF}\""] + ]], + ["comment", "# hexadecimal unicode character"], + + ["string-literal", [ + ["string", "\"\\101\""] + ]], + ["comment", "# => \"A\""], + + ["string-literal", [ + ["string", "\"\\123\""] + ]], + ["comment", "# => \"S\""], + + ["string-literal", [ + ["string", "\"\\12\""] + ]], + ["comment", "# => \"\\n\""], + + ["string-literal", [ + ["string", "\"\\1\""] + ]], + ["comment", "# string with one character with code point 1"], + + ["string-literal", [ + ["string", "\"\\u{48 45 4C 4C 4F}\""] + ]], + ["comment", "# => \"HELLO\""], + + ["string-literal", [ + ["string", "\"sum: "], + ["interpolation", [ + ["delimiter", "#{"], + ["content", ["a"]], + ["delimiter", "}"] + ]], + ["string", " + "], + ["interpolation", [ + ["delimiter", "#{"], + ["content", ["b"]], + ["delimiter", "}"] + ]], + ["string", " = "], + ["interpolation", [ + ["delimiter", "#{"], + ["content", [ + "a ", + ["operator", "+"], + " b" + ]], + ["delimiter", "}"] + ]], + ["string", "\""] + ]], + + ["string-literal", [ + ["string", "\"\\#{a + b}\""] + ]], + ["comment", "# => \"#{a + b}\""], + + ["string-literal", [ + ["string", "%q("], + ["interpolation", [ + ["delimiter", "#{"], + ["content", [ + "a ", + ["operator", "+"], + " b" + ]], + ["delimiter", "}"] + ]], + ["string", ")"] + ]], + ["comment", "# => \"#{a + b}\""], + + ["string-literal", [ + ["string", "%(hello (\"world\"))"] + ]], + ["comment", "# => \"hello (\\\"world\\\")\""], + + ["string-literal", [ + ["string", "%[hello [\"world\"]]"] + ]], + ["comment", "# => \"hello [\\\"world\\\"]\""], + + ["string-literal", [ + ["string", "%{hello {\"world\"}}"] + ]], + ["comment", "# => \"hello {\\\"world\\\"}\""], + + ["string-literal", [ + ["string", "%>"] + ]], + ["comment", "# => \"hello <\\\"world\\\">\""], + + ["string-literal", [ + ["string", "%|hello \"world\"|"] + ]], + ["comment", "# => \"hello \\\"world\\\"\""], + + "\r\n\r\nname ", + ["operator", "="], + ["string-literal", [ + ["string", "\"world\""] + ]], + + ["string-literal", [ + ["string", "%q(hello \\n "], + ["interpolation", [ + ["delimiter", "#{"], + ["content", ["name"]], + ["delimiter", "}"] + ]], + ["string", ")"] + ]], + ["comment", "# => \"hello \\\\n \\#{name}\""], + + ["string-literal", [ + ["string", "%Q(hello \\n "], + ["interpolation", [ + ["delimiter", "#{"], + ["content", ["name"]], + ["delimiter", "}"] + ]], + ["string", ")"] + ]], + ["comment", "# => \"hello \\n world\""], + + ["string-literal", [ + ["string", "%w(foo bar baz)"] + ]], + ["comment", "# => [\"foo\", \"bar\", \"baz\"]"], + + ["string-literal", [ + ["string", "%w(foo\\nbar baz)"] + ]], + ["comment", "# => [\"foo\\\\nbar\", \"baz\"]"], + + ["string-literal", [ + ["string", "%w(foo(bar) baz)"] + ]], + ["comment", "# => [\"foo(bar)\", \"baz\"]"], + + ["string-literal", [ + ["string", "%w(foo\\ bar baz)"] + ]], + ["comment", "# => [\"foo bar\", \"baz\"]"], + + ["string-literal", [ + ["string", "\"hello \""] + ]], + ["punctuation", "\\"], + + ["string-literal", [ + ["string", "\"world, \""] + ]], + ["punctuation", "\\"], + + ["string-literal", [ + ["string", "\"no newlines\""] + ]], + ["comment", "# same as \"hello world, no newlines\""], + + ["string-literal", [ + ["string", "\"hello \\\r\n world, \\\r\n no newlines\""] + ]], + ["comment", "# same as \"hello world, no newlines\""], + + ["string-literal", [ + ["delimiter", [ + ["punctuation", "<<-"], + ["symbol", "XML"] + ]], + ["string", "\r\n\r\n \r\n\r\n"], + ["delimiter", [ + ["symbol", "XML"] + ]] + ]] +] diff --git a/tests/languages/crystal/symbol_feature.test b/tests/languages/crystal/symbol_feature.test new file mode 100644 index 0000000000..d585682131 --- /dev/null +++ b/tests/languages/crystal/symbol_feature.test @@ -0,0 +1,17 @@ +:unquoted_symbol +:"quoted symbol" +:"a" # identical to :a +:あ +:question? +:exclamation! + +---------------------------------------------------- + +[ + ["symbol", ":unquoted_symbol"], + ["symbol", ":\"quoted symbol\""], + ["symbol", ":\"a\""], ["comment", "# identical to :a"], + ["symbol", ":あ"], + ["symbol", ":question?"], + ["symbol", ":exclamation!"] +]