From dd9382a102505ffde8b667866532879c0c919747 Mon Sep 17 00:00:00 2001 From: Michael Schmidt Date: Mon, 11 May 2020 14:49:10 +0200 Subject: [PATCH] Rust: Improvements (#2332) This makes several improvements to Rust. This includes support for multiline strings, better closures, attributes, macros, and comments, an update for the keyword list, and more. --- components/prism-rust.js | 154 +++++++++++------- components/prism-rust.min.js | 2 +- tests/languages/rust/attribute_feature.test | 28 +++- tests/languages/rust/boolean_feature.test | 13 ++ .../rust/closure-params_feature.test | 118 +++++++++++++- tests/languages/rust/comment_feature.test | 11 +- tests/languages/rust/function_feature.test | 56 +++++-- tests/languages/rust/issue1339.test | 6 +- tests/languages/rust/keyword_feature.test | 128 +++++++++++---- .../rust/lifetime-annotation_feature.test | 6 +- tests/languages/rust/macro_example.test | 144 ++++++++++++++++ ...-rules_feature.test => macro_feature.test} | 8 +- tests/languages/rust/number_feature.test | 8 +- tests/languages/rust/operator_feature.test | 4 +- tests/languages/rust/string_feature.test | 26 ++- 15 files changed, 583 insertions(+), 129 deletions(-) create mode 100644 tests/languages/rust/boolean_feature.test create mode 100644 tests/languages/rust/macro_example.test rename tests/languages/rust/{macro-rules_feature.test => macro_feature.test} (52%) diff --git a/components/prism-rust.js b/components/prism-rust.js index a2b9ae2599..cb42b75498 100644 --- a/components/prism-rust.js +++ b/components/prism-rust.js @@ -1,68 +1,100 @@ -/* TODO - Add support for Markdown notation inside doc comments - Add support for nested block comments... - Match closure params even when not followed by dash or brace - Add better support for macro definition -*/ +(function (Prism) { -Prism.languages.rust = { - 'comment': [ - { - pattern: /(^|[^\\])\/\*[\s\S]*?\*\//, - lookbehind: true - }, - { - pattern: /(^|[^\\:])\/\/.*/, - lookbehind: true - } - ], - 'string': [ - { - pattern: /b?r(#*)"(?:\\.|(?!"\1)[^\\\r\n])*"\1/, + var multilineComment = /\/\*(?:[^*/]|\*(?!\/)|\/(?!\*)|)*\*\//.source; + for (var i = 0; i < 2; i++) { + // support 4 levels of nested comments + multilineComment = multilineComment.replace(//g, function () { return multilineComment; }); + } + multilineComment = multilineComment.replace(//g, function () { return /[^\s\S]/.source; }); + + + Prism.languages.rust = { + 'comment': [ + { + pattern: RegExp(/(^|[^\\])/.source + multilineComment), + lookbehind: true, + greedy: true + }, + { + pattern: /(^|[^\\:])\/\/.*/, + lookbehind: true, + greedy: true + } + ], + 'string': { + pattern: /b?"(?:\\[\s\S]|[^\\"])*"|b?r(#*)"(?:[^"]|"(?!\1))*"\1/, greedy: true }, - { - pattern: /b?"(?:\\.|[^\\\r\n"])*"/, - greedy: true - } - ], - 'char': { - pattern: /b?'(?:\\(?:x[0-7][\da-fA-F]|u{(?:[\da-fA-F]_*){1,6}|.)|[^\\\r\n\t'])'/, - alias: 'string' - }, - 'lifetime-annotation': { - pattern: /'[^\s>']+/, - alias: 'symbol' - }, - 'keyword': /\b(?:abstract|alignof|as|async|await|be|box|break|const|continue|crate|do|dyn|else|enum|extern|false|final|fn|for|if|impl|in|let|loop|match|mod|move|mut|offsetof|once|override|priv|pub|pure|ref|return|sizeof|static|self|Self|struct|super|true|trait|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/, + 'char': { + pattern: /b?'(?:\\(?:x[0-7][\da-fA-F]|u{(?:[\da-fA-F]_*){1,6}|.)|[^\\\r\n\t'])'/, + greedy: true, + alias: 'string' + }, + 'attribute': { + pattern: /#!?\[[^[\]]*\]/, + greedy: true, + alias: 'attr-name', + inside: { + 'string': null // see below + } + }, + + // Closure params should not be confused with bitwise OR | + 'closure-params': { + pattern: /([=(,:]\s*|\bmove\s*)\|[^|]*\||\|[^|]*\|(?=\s*(?:\{|->))/, + lookbehind: true, + greedy: true, + inside: { + 'closure-punctuation': { + pattern: /^\||\|$/, + alias: 'punctuation' + }, + rest: null // see below + } + }, - 'attribute': { - pattern: /#!?\[.+?\]/, - greedy: true, - alias: 'attr-name' - }, + 'lifetime-annotation': { + pattern: /'\w+/, + alias: 'symbol' + }, + + 'fragment-specifier': { + pattern: /(\$\w+:)[a-z]+/, + lookbehind: true, + alias: 'punctuation' + }, + 'variable': /\$\w+/, + + 'function-definition': { + pattern: /(\bfn\s*)\w+/, + lookbehind: true, + alias: 'function' + }, + 'keyword': [ + // https://github.com/rust-lang/reference/blob/master/src/keywords.md + /\b(?:abstract|as|async|await|become|box|break|const|continue|crate|do|dyn|else|enum|extern|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|override|priv|pub|ref|return|self|Self|static|struct|super|trait|try|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/, + // primitives + // https://doc.rust-lang.org/stable/rust-by-example/primitives.html + /\b(?:[ui](?:8|16|32|64|128|size)|f(?:32|64)|bool|char)\b/ + ], + + // functions can technically start with an upper-case letter, but this will introduce a lot of false positives + // and Rust's naming conventions recommend snake_case anyway. + // https://doc.rust-lang.org/1.0.0/style/style/naming/README.html + 'function': /\b[a-z_]\w*(?=\s*(?:::\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*)?\()/, + 'macro': { + pattern: /\w+!/, + alias: 'property' + }, - 'function': [ - /\w+(?=\s*\()/, - // Macros can use parens or brackets - /\w+!(?=\s*\(|\[)/ - ], - 'macro-rules': { - pattern: /\w+!/, - alias: 'function' - }, + // Hex, oct, bin, dec numbers with visual separators and type suffix + 'number': /\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:\d(?:_?\d)*)?\.?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:[iu](?:8|16|32|64|size)?|f32|f64))?\b/, + 'boolean': /\b(?:false|true)\b/, + 'punctuation': /->|\.\.=|\.{1,3}|::|[{}[\];(),:]/, + 'operator': /[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<>?=?|[@?]/ + }; - // Hex, oct, bin, dec numbers with visual separators and type suffix - 'number': /\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:\d(?:_?\d)*)?\.?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:[iu](?:8|16|32|64)?|f32|f64))?\b/, + Prism.languages.rust['closure-params'].inside.rest = Prism.languages.rust; + Prism.languages.rust['attribute'].inside['string'] = Prism.languages.rust['string']; - // Closure params should not be confused with bitwise OR | - 'closure-params': { - pattern: /\|[^|]*\|(?=\s*[{-])/, - inside: { - 'punctuation': /[|:,]/, - 'operator': /[&*]/ - } - }, - 'punctuation': /->|\.\.=|\.{1,3}|::|[{}[\];(),:]/, - 'operator': /[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<>?=?|[@?]/ -}; +}(Prism)); diff --git a/components/prism-rust.min.js b/components/prism-rust.min.js index 0535651161..aaad309fa5 100644 --- a/components/prism-rust.min.js +++ b/components/prism-rust.min.js @@ -1 +1 @@ -Prism.languages.rust={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?\*\//,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0}],string:[{pattern:/b?r(#*)"(?:\\.|(?!"\1)[^\\\r\n])*"\1/,greedy:!0},{pattern:/b?"(?:\\.|[^\\\r\n"])*"/,greedy:!0}],char:{pattern:/b?'(?:\\(?:x[0-7][\da-fA-F]|u{(?:[\da-fA-F]_*){1,6}|.)|[^\\\r\n\t'])'/,alias:"string"},"lifetime-annotation":{pattern:/'[^\s>']+/,alias:"symbol"},keyword:/\b(?:abstract|alignof|as|async|await|be|box|break|const|continue|crate|do|dyn|else|enum|extern|false|final|fn|for|if|impl|in|let|loop|match|mod|move|mut|offsetof|once|override|priv|pub|pure|ref|return|sizeof|static|self|Self|struct|super|true|trait|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/,attribute:{pattern:/#!?\[.+?\]/,greedy:!0,alias:"attr-name"},function:[/\w+(?=\s*\()/,/\w+!(?=\s*\(|\[)/],"macro-rules":{pattern:/\w+!/,alias:"function"},number:/\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:\d(?:_?\d)*)?\.?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:[iu](?:8|16|32|64)?|f32|f64))?\b/,"closure-params":{pattern:/\|[^|]*\|(?=\s*[{-])/,inside:{punctuation:/[|:,]/,operator:/[&*]/}},punctuation:/->|\.\.=|\.{1,3}|::|[{}[\];(),:]/,operator:/[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<>?=?|[@?]/}; \ No newline at end of file +!function(e){for(var t="/\\*(?:[^*/]|\\*(?!/)|/(?!\\*)|)*\\*/",a=0;a<2;a++)t=t.replace(//g,function(){return t});t=t.replace(//g,function(){return"[^\\s\\S]"}),e.languages.rust={comment:[{pattern:RegExp("(^|[^\\\\])"+t),lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/b?"(?:\\[\s\S]|[^\\"])*"|b?r(#*)"(?:[^"]|"(?!\1))*"\1/,greedy:!0},char:{pattern:/b?'(?:\\(?:x[0-7][\da-fA-F]|u{(?:[\da-fA-F]_*){1,6}|.)|[^\\\r\n\t'])'/,greedy:!0,alias:"string"},attribute:{pattern:/#!?\[[^[\]]*\]/,greedy:!0,alias:"attr-name",inside:{string:null}},"closure-params":{pattern:/([=(,:]\s*|\bmove\s*)\|[^|]*\||\|[^|]*\|(?=\s*(?:\{|->))/,lookbehind:!0,greedy:!0,inside:{"closure-punctuation":{pattern:/^\||\|$/,alias:"punctuation"},rest:null}},"lifetime-annotation":{pattern:/'\w+/,alias:"symbol"},"fragment-specifier":{pattern:/(\$\w+:)[a-z]+/,lookbehind:!0,alias:"punctuation"},variable:/\$\w+/,"function-definition":{pattern:/(\bfn\s*)\w+/,lookbehind:!0,alias:"function"},keyword:[/\b(?:abstract|as|async|await|become|box|break|const|continue|crate|do|dyn|else|enum|extern|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|override|priv|pub|ref|return|self|Self|static|struct|super|trait|try|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/,/\b(?:[ui](?:8|16|32|64|128|size)|f(?:32|64)|bool|char)\b/],function:/\b[a-z_]\w*(?=\s*(?:::\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*)?\()/,macro:{pattern:/\w+!/,alias:"property"},number:/\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:\d(?:_?\d)*)?\.?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:[iu](?:8|16|32|64|size)?|f32|f64))?\b/,boolean:/\b(?:false|true)\b/,punctuation:/->|\.\.=|\.{1,3}|::|[{}[\];(),:]/,operator:/[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<>?=?|[@?]/},e.languages.rust["closure-params"].inside.rest=e.languages.rust,e.languages.rust.attribute.inside.string=e.languages.rust.string}(Prism); \ No newline at end of file diff --git a/tests/languages/rust/attribute_feature.test b/tests/languages/rust/attribute_feature.test index a3dac8a871..e2475dd738 100644 --- a/tests/languages/rust/attribute_feature.test +++ b/tests/languages/rust/attribute_feature.test @@ -1,13 +1,35 @@ #[test] #![warn(unstable)] +#[doc(hidden)] +#[unstable( + feature = "thread_local_internals", + reason = "recently added to create a key", + issue = "none" +)] ---------------------------------------------------- [ - ["attribute", "#[test]"], - ["attribute", "#![warn(unstable)]"] + ["attribute", [ + "#[test]" + ]], + ["attribute", [ + "#![warn(unstable)]" + ]], + ["attribute", [ + "#[doc(hidden)]" + ]], + ["attribute", [ + "#[unstable(\r\n\tfeature = ", + ["string", "\"thread_local_internals\""], + ",\r\n\treason = ", + ["string", "\"recently added to create a key\""], + ",\r\n\tissue = ", + ["string", "\"none\""], + "\r\n)]" + ]] ] ---------------------------------------------------- -Checks for attributes. \ No newline at end of file +Checks for attributes. diff --git a/tests/languages/rust/boolean_feature.test b/tests/languages/rust/boolean_feature.test new file mode 100644 index 0000000000..a4e4d4bc5c --- /dev/null +++ b/tests/languages/rust/boolean_feature.test @@ -0,0 +1,13 @@ +false +true + +---------------------------------------------------- + +[ + ["boolean", "false"], + ["boolean", "true"] +] + +---------------------------------------------------- + +Checks for booleans. diff --git a/tests/languages/rust/closure-params_feature.test b/tests/languages/rust/closure-params_feature.test index 83bf90004c..4af3effdb5 100644 --- a/tests/languages/rust/closure-params_feature.test +++ b/tests/languages/rust/closure-params_feature.test @@ -1,11 +1,19 @@ |x: int, y: int| -> int {} || {} +vec1.iter().any(|&x| x == 2); +foo(123, || x * x); + +let add_one_v2 = |x: u32| -> u32 { x + 1 }; +let add_one_v3 = |x| { x + 1 }; +let add_one_v4 = |x| x + 1 ; +move || println!("This is a: {}", text) + ---------------------------------------------------- [ ["closure-params", [ - ["punctuation", "|"], + ["closure-punctuation", "|"], "x", ["punctuation", ":"], " int", @@ -13,18 +21,114 @@ " y", ["punctuation", ":"], " int", - ["punctuation", "|"] + ["closure-punctuation", "|"] + ]], + ["punctuation", "->"], + " int ", + ["punctuation", "{"], + ["punctuation", "}"], + + ["closure-params", [ + ["closure-punctuation", "|"], + ["closure-punctuation", "|"] + ]], + ["punctuation", "{"], + ["punctuation", "}"], + + "\r\n\r\nvec1", + ["punctuation", "."], + ["function", "iter"], + ["punctuation", "("], + ["punctuation", ")"], + ["punctuation", "."], + ["function", "any"], + ["punctuation", "("], + ["closure-params", [ + ["closure-punctuation", "|"], + ["operator", "&"], + "x", + ["closure-punctuation", "|"] + ]], + " x ", + ["operator", "=="], + ["number", "2"], + ["punctuation", ")"], + ["punctuation", ";"], + + ["function", "foo"], + ["punctuation", "("], + ["number", "123"], + ["punctuation", ","], + ["closure-params", [ + ["closure-punctuation", "|"], + ["closure-punctuation", "|"] + ]], + " x ", + ["operator", "*"], + " x", + ["punctuation", ")"], + ["punctuation", ";"], + + ["keyword", "let"], + " add_one_v2 ", + ["operator", "="], + ["closure-params", [ + ["closure-punctuation", "|"], + "x", + ["punctuation", ":"], + ["keyword", "u32"], + ["closure-punctuation", "|"] ]], ["punctuation", "->"], - " int ", ["punctuation", "{"], ["punctuation", "}"], + ["keyword", "u32"], + ["punctuation", "{"], + " x ", + ["operator", "+"], + ["number", "1"], + ["punctuation", "}"], + ["punctuation", ";"], + + ["keyword", "let"], + " add_one_v3 ", + ["operator", "="], + ["closure-params", [ + ["closure-punctuation", "|"], + "x", + ["closure-punctuation", "|"] + ]], + ["punctuation", "{"], + " x ", + ["operator", "+"], + ["number", "1"], + ["punctuation", "}"], + ["punctuation", ";"], + + ["keyword", "let"], + " add_one_v4 ", + ["operator", "="], + ["closure-params", [ + ["closure-punctuation", "|"], + "x", + ["closure-punctuation", "|"] + ]], + " x ", + ["operator", "+"], + ["number", "1"], + ["punctuation", ";"], + ["keyword", "move"], ["closure-params", [ - ["punctuation", "|"], - ["punctuation", "|"] + ["closure-punctuation", "|"], + ["closure-punctuation", "|"] ]], - ["punctuation", "{"], ["punctuation", "}"] + ["macro", "println!"], + ["punctuation", "("], + ["string", "\"This is a: {}\""], + ["punctuation", ","], + " text", + ["punctuation", ")"] ] ---------------------------------------------------- -Checks for closure params. \ No newline at end of file +Checks for closure params. diff --git a/tests/languages/rust/comment_feature.test b/tests/languages/rust/comment_feature.test index 936702840e..84e1e99e5f 100644 --- a/tests/languages/rust/comment_feature.test +++ b/tests/languages/rust/comment_feature.test @@ -4,15 +4,22 @@ /* foo bar */ +/* /* */ /** */ /*! */ */ +/*! /* */ /** */ /*! */ */ +/** /* */ /** */ /*! */ */ + ---------------------------------------------------- [ ["comment", "//"], ["comment", "// foobar"], ["comment", "/**/"], - ["comment", "/* foo\r\nbar */"] + ["comment", "/* foo\r\nbar */"], + ["comment", "/* /* */ /** */ /*! */ */"], + ["comment", "/*! /* */ /** */ /*! */ */"], + ["comment", "/** /* */ /** */ /*! */ */"] ] ---------------------------------------------------- -Checks for comments. \ No newline at end of file +Checks for comments. diff --git a/tests/languages/rust/function_feature.test b/tests/languages/rust/function_feature.test index 63fcc8b94d..c4a51d434e 100644 --- a/tests/languages/rust/function_feature.test +++ b/tests/languages/rust/function_feature.test @@ -2,22 +2,58 @@ foo ( foobar( foo_bar_42( -foo! ( -foobar![ -foo_bar_42!( +foo_generic::>() + +fn apply(f: F) where F: FnOnce() { + f(); +} ---------------------------------------------------- [ - ["function", "foo"], ["punctuation", "("], - ["function", "foobar"], ["punctuation", "("], - ["function", "foo_bar_42"], ["punctuation", "("], + ["function", "foo"], + ["punctuation", "("], + ["function", "foobar"], + ["punctuation", "("], + ["function", "foo_bar_42"], + ["punctuation", "("], + + ["function", "foo_generic"], + ["punctuation", "::"], + ["operator", "<"], + "T", + ["punctuation", ","], + " Option", + ["operator", "<"], + "T", + ["operator", ">>"], + ["punctuation", "("], + ["punctuation", ")"], - ["function", "foo!"], ["punctuation", "("], - ["function", "foobar!"], ["punctuation", "["], - ["function", "foo_bar_42!"], ["punctuation", "("] + ["keyword", "fn"], + ["function-definition", "apply"], + ["operator", "<"], + "F", + ["operator", ">"], + ["punctuation", "("], + "f", + ["punctuation", ":"], + " F", + ["punctuation", ")"], + ["keyword", "where"], + " F", + ["punctuation", ":"], + " FnOnce", + ["punctuation", "("], + ["punctuation", ")"], + ["punctuation", "{"], + ["function", "f"], + ["punctuation", "("], + ["punctuation", ")"], + ["punctuation", ";"], + ["punctuation", "}"] ] ---------------------------------------------------- -Checks for functions and macros. \ No newline at end of file +Checks for functions and macros. diff --git a/tests/languages/rust/issue1339.test b/tests/languages/rust/issue1339.test index 1dd3208f59..df5d7d8723 100644 --- a/tests/languages/rust/issue1339.test +++ b/tests/languages/rust/issue1339.test @@ -12,7 +12,7 @@ fn foo<'a> (first: &'a str, second: &'a str) => () { } ["punctuation", "["], ["operator", "&"], ["lifetime-annotation", "'static"], - " char", + ["keyword", "char"], ["punctuation", "]"], ["operator", "="], ["operator", "&"], @@ -20,7 +20,7 @@ fn foo<'a> (first: &'a str, second: &'a str) => () { } ["string", "\"2\""], ["punctuation", "]"], ["keyword", "fn"], - " foo", + ["function-definition", "foo"], ["operator", "<"], ["lifetime-annotation", "'a"], ["operator", ">"], @@ -46,4 +46,4 @@ fn foo<'a> (first: &'a str, second: &'a str) => () { } ---------------------------------------------------- -Checks for lifetime annotations in real-world examples. See #1339. \ No newline at end of file +Checks for lifetime annotations in real-world examples. See #1339. diff --git a/tests/languages/rust/keyword_feature.test b/tests/languages/rust/keyword_feature.test index 68b2a623ef..5ec2bb7a6b 100644 --- a/tests/languages/rust/keyword_feature.test +++ b/tests/languages/rust/keyword_feature.test @@ -1,39 +1,109 @@ -abstract alignof as async -await be box break const -continue crate do dyn -else enum extern -false final fn for -if impl in let loop -match mod move mut -offsetof once override -priv pub pure ref -return sizeof static -self Self struct super -true trait type typeof -union unsafe unsized use -virtual where while +abstract +as +async +await +become +box +break +const +continue +crate +do +dyn +else +enum +extern +final +fn; +for +if +impl +in +let +loop +macro +match +mod +move +mut +override +priv +pub +ref +return +self +Self +static +struct +super +trait +try +type +typeof +union +unsafe +unsized +use +virtual +where +while yield ---------------------------------------------------- [ - ["keyword", "abstract"], ["keyword", "alignof"], ["keyword", "as"], ["keyword", "async"], ["keyword", "await"], - ["keyword", "be"], ["keyword", "box"], ["keyword", "break"], ["keyword", "const"], - ["keyword", "continue"], ["keyword", "crate"], ["keyword", "do"], ["keyword", "dyn"], - ["keyword", "else"], ["keyword", "enum"], ["keyword", "extern"], - ["keyword", "false"], ["keyword", "final"], ["keyword", "fn"], ["keyword", "for"], - ["keyword", "if"], ["keyword", "impl"], ["keyword", "in"], ["keyword", "let"], ["keyword", "loop"], - ["keyword", "match"], ["keyword", "mod"], ["keyword", "move"], ["keyword", "mut"], - ["keyword", "offsetof"], ["keyword", "once"], ["keyword", "override"], - ["keyword", "priv"], ["keyword", "pub"], ["keyword", "pure"], ["keyword", "ref"], - ["keyword", "return"], ["keyword", "sizeof"], ["keyword", "static"], - ["keyword", "self"], ["keyword", "Self"], ["keyword", "struct"], ["keyword", "super"], - ["keyword", "true"], ["keyword", "trait"], ["keyword", "type"], ["keyword", "typeof"], - ["keyword", "union"], ["keyword", "unsafe"], ["keyword", "unsized"], ["keyword", "use"], - ["keyword", "virtual"], ["keyword", "where"], ["keyword", "while"], + ["keyword", "abstract"], + ["keyword", "as"], + ["keyword", "async"], + ["keyword", "await"], + ["keyword", "become"], + ["keyword", "box"], + ["keyword", "break"], + ["keyword", "const"], + ["keyword", "continue"], + ["keyword", "crate"], + ["keyword", "do"], + ["keyword", "dyn"], + ["keyword", "else"], + ["keyword", "enum"], + ["keyword", "extern"], + ["keyword", "final"], + ["keyword", "fn"], ["punctuation", ";"], + ["keyword", "for"], + ["keyword", "if"], + ["keyword", "impl"], + ["keyword", "in"], + ["keyword", "let"], + ["keyword", "loop"], + ["keyword", "macro"], + ["keyword", "match"], + ["keyword", "mod"], + ["keyword", "move"], + ["keyword", "mut"], + ["keyword", "override"], + ["keyword", "priv"], + ["keyword", "pub"], + ["keyword", "ref"], + ["keyword", "return"], + ["keyword", "self"], + ["keyword", "Self"], + ["keyword", "static"], + ["keyword", "struct"], + ["keyword", "super"], + ["keyword", "trait"], + ["keyword", "try"], + ["keyword", "type"], + ["keyword", "typeof"], + ["keyword", "union"], + ["keyword", "unsafe"], + ["keyword", "unsized"], + ["keyword", "use"], + ["keyword", "virtual"], + ["keyword", "where"], + ["keyword", "while"], ["keyword", "yield"] ] ---------------------------------------------------- -Checks for all keywords. \ No newline at end of file +Checks for all keywords. diff --git a/tests/languages/rust/lifetime-annotation_feature.test b/tests/languages/rust/lifetime-annotation_feature.test index 02c813debc..5af0e9740a 100644 --- a/tests/languages/rust/lifetime-annotation_feature.test +++ b/tests/languages/rust/lifetime-annotation_feature.test @@ -1,15 +1,19 @@ +'static 'foo 'a +'_ <'a> ---------------------------------------------------- [ + ["lifetime-annotation", "'static"], ["lifetime-annotation", "'foo"], ["lifetime-annotation", "'a"], + ["lifetime-annotation", "'_"], ["operator", "<"], ["lifetime-annotation", "'a"], ["operator", ">"] ] ---------------------------------------------------- -Checks for lifetime annotations. \ No newline at end of file +Checks for lifetime annotations. diff --git a/tests/languages/rust/macro_example.test b/tests/languages/rust/macro_example.test new file mode 100644 index 0000000000..593fe2f90a --- /dev/null +++ b/tests/languages/rust/macro_example.test @@ -0,0 +1,144 @@ +macro_rules! write_html { + ($w:expr, ) => (()); + + ($w:expr, $e:tt) => (write!($w, "{}", $e)); + + ($w:expr, $tag:ident [ $($inner:tt)* ] $($rest:tt)*) => {{ + write!($w, "<{}>", stringify!($tag)); + write_html!($w, $($inner)*); + write!($w, "", stringify!($tag)); + write_html!($w, $($rest)*); + }}; +} + +---------------------------------------------------- + +[ + ["macro", "macro_rules!"], + " write_html ", + ["punctuation", "{"], + + ["punctuation", "("], + ["variable", "$w"], + ["punctuation", ":"], + ["fragment-specifier", "expr"], + ["punctuation", ","], + ["punctuation", ")"], + ["operator", "=>"], + ["punctuation", "("], + ["punctuation", "("], + ["punctuation", ")"], + ["punctuation", ")"], + ["punctuation", ";"], + + ["punctuation", "("], + ["variable", "$w"], + ["punctuation", ":"], + ["fragment-specifier", "expr"], + ["punctuation", ","], + ["variable", "$e"], + ["punctuation", ":"], + ["fragment-specifier", "tt"], + ["punctuation", ")"], + ["operator", "=>"], + ["punctuation", "("], + ["macro", "write!"], + ["punctuation", "("], + ["variable", "$w"], + ["punctuation", ","], + ["string", "\"{}\""], + ["punctuation", ","], + ["variable", "$e"], + ["punctuation", ")"], + ["punctuation", ")"], + ["punctuation", ";"], + + ["punctuation", "("], + ["variable", "$w"], + ["punctuation", ":"], + ["fragment-specifier", "expr"], + ["punctuation", ","], + ["variable", "$tag"], + ["punctuation", ":"], + ["fragment-specifier", "ident"], + ["punctuation", "["], + " $", + ["punctuation", "("], + ["variable", "$inner"], + ["punctuation", ":"], + ["fragment-specifier", "tt"], + ["punctuation", ")"], + ["operator", "*"], + ["punctuation", "]"], + " $", + ["punctuation", "("], + ["variable", "$rest"], + ["punctuation", ":"], + ["fragment-specifier", "tt"], + ["punctuation", ")"], + ["operator", "*"], + ["punctuation", ")"], + ["operator", "=>"], + ["punctuation", "{"], + ["punctuation", "{"], + + ["macro", "write!"], + ["punctuation", "("], + ["variable", "$w"], + ["punctuation", ","], + ["string", "\"<{}>\""], + ["punctuation", ","], + ["macro", "stringify!"], + ["punctuation", "("], + ["variable", "$tag"], + ["punctuation", ")"], + ["punctuation", ")"], + ["punctuation", ";"], + + ["macro", "write_html!"], + ["punctuation", "("], + ["variable", "$w"], + ["punctuation", ","], + " $", + ["punctuation", "("], + ["variable", "$inner"], + ["punctuation", ")"], + ["operator", "*"], + ["punctuation", ")"], + ["punctuation", ";"], + + ["macro", "write!"], + ["punctuation", "("], + ["variable", "$w"], + ["punctuation", ","], + ["string", "\"\""], + ["punctuation", ","], + ["macro", "stringify!"], + ["punctuation", "("], + ["variable", "$tag"], + ["punctuation", ")"], + ["punctuation", ")"], + ["punctuation", ";"], + + ["macro", "write_html!"], + ["punctuation", "("], + ["variable", "$w"], + ["punctuation", ","], + " $", + ["punctuation", "("], + ["variable", "$rest"], + ["punctuation", ")"], + ["operator", "*"], + ["punctuation", ")"], + ["punctuation", ";"], + + ["punctuation", "}"], + ["punctuation", "}"], + ["punctuation", ";"], + + ["punctuation", "}"] +] + +---------------------------------------------------- + +Checks this macro example. diff --git a/tests/languages/rust/macro-rules_feature.test b/tests/languages/rust/macro_feature.test similarity index 52% rename from tests/languages/rust/macro-rules_feature.test rename to tests/languages/rust/macro_feature.test index 9d30051c3a..ba91479ace 100644 --- a/tests/languages/rust/macro-rules_feature.test +++ b/tests/languages/rust/macro_feature.test @@ -5,11 +5,11 @@ foo_bar_42! ---------------------------------------------------- [ - ["macro-rules", "foo!"], - ["macro-rules", "foo_bar!"], - ["macro-rules", "foo_bar_42!"] + ["macro", "foo!"], + ["macro", "foo_bar!"], + ["macro", "foo_bar_42!"] ] ---------------------------------------------------- -Checks for macro rules. \ No newline at end of file +Checks for macros. diff --git a/tests/languages/rust/number_feature.test b/tests/languages/rust/number_feature.test index 61d6e8a5e7..b4857e9dec 100644 --- a/tests/languages/rust/number_feature.test +++ b/tests/languages/rust/number_feature.test @@ -18,6 +18,8 @@ 4.2f32 4.2f64 +0usize + ---------------------------------------------------- [ @@ -39,9 +41,11 @@ ["number", "3.5E-8u64"], ["number", "4.6e+41i64"], ["number", "4.2f32"], - ["number", "4.2f64"] + ["number", "4.2f64"], + + ["number", "0usize"] ] ---------------------------------------------------- -Checks for numbers. \ No newline at end of file +Checks for numbers. diff --git a/tests/languages/rust/operator_feature.test b/tests/languages/rust/operator_feature.test index ae188f8bc7..ca49cf2d7a 100644 --- a/tests/languages/rust/operator_feature.test +++ b/tests/languages/rust/operator_feature.test @@ -6,7 +6,7 @@ ! != ^ ^= = == => -& && &= +& && &= ; | || |= < << <= <<= > >> >= >>= @@ -23,7 +23,7 @@ ["operator", "!"], ["operator", "!="], ["operator", "^"], ["operator", "^="], ["operator", "="], ["operator", "=="], ["operator", "=>"], - ["operator", "&"], ["operator", "&&"], ["operator", "&="], + ["operator", "&"], ["operator", "&&"], ["operator", "&="], ["punctuation", ";"], ["operator", "|"], ["operator", "||"], ["operator", "|="], ["operator", "<"], ["operator", "<<"], ["operator", "<="], ["operator", "<<="], ["operator", ">"], ["operator", ">>"], ["operator", ">="], ["operator", ">>="], diff --git a/tests/languages/rust/string_feature.test b/tests/languages/rust/string_feature.test index c0667e2668..c9f7637d84 100644 --- a/tests/languages/rust/string_feature.test +++ b/tests/languages/rust/string_feature.test @@ -1,35 +1,53 @@ "" "fo\"obar" +"foo\ + bar" +"foo +bar" b"" b"fo\"obar" r#""# r#"fo"obar"# -r###"foo#bar"### +r###"foo +# +bar"### br#""# br#"fo"obar"# br###"foo#bar"### +r"(?x) +(?P\d{4}) # the year +- +(?P\d{2}) # the month +- +(?P\d{2}) # the day +" + ---------------------------------------------------- [ ["string", "\"\""], ["string", "\"fo\\\"obar\""], + ["string", "\"foo\\\r\n\tbar\""], + ["string", "\"foo\r\nbar\""], ["string", "b\"\""], ["string", "b\"fo\\\"obar\""], ["string", "r#\"\"#"], ["string", "r#\"fo\"obar\"#"], - ["string", "r###\"foo#bar\"###"], + ["string", "r###\"foo\r\n#\r\nbar\"###"], ["string", "br#\"\"#"], ["string", "br#\"fo\"obar\"#"], - ["string", "br###\"foo#bar\"###"] + ["string", "br###\"foo#bar\"###"], + + ["string", "r\"(?x)\r\n(?P\\d{4}) # the year\r\n-\r\n(?P\\d{2}) # the month\r\n-\r\n(?P\\d{2}) # the day\r\n\""] ] ---------------------------------------------------- -Checks for strings. \ No newline at end of file +Checks for strings.