Skip to content

Commit 194c542

Browse files
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.
1 parent e523f5d commit 194c542

15 files changed

+583
-129
lines changed

components/prism-rust.js

+93-61
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,100 @@
1-
/* TODO
2-
Add support for Markdown notation inside doc comments
3-
Add support for nested block comments...
4-
Match closure params even when not followed by dash or brace
5-
Add better support for macro definition
6-
*/
1+
(function (Prism) {
72

8-
Prism.languages.rust = {
9-
'comment': [
10-
{
11-
pattern: /(^|[^\\])\/\*[\s\S]*?\*\//,
12-
lookbehind: true
13-
},
14-
{
15-
pattern: /(^|[^\\:])\/\/.*/,
16-
lookbehind: true
17-
}
18-
],
19-
'string': [
20-
{
21-
pattern: /b?r(#*)"(?:\\.|(?!"\1)[^\\\r\n])*"\1/,
3+
var multilineComment = /\/\*(?:[^*/]|\*(?!\/)|\/(?!\*)|<self>)*\*\//.source;
4+
for (var i = 0; i < 2; i++) {
5+
// support 4 levels of nested comments
6+
multilineComment = multilineComment.replace(/<self>/g, function () { return multilineComment; });
7+
}
8+
multilineComment = multilineComment.replace(/<self>/g, function () { return /[^\s\S]/.source; });
9+
10+
11+
Prism.languages.rust = {
12+
'comment': [
13+
{
14+
pattern: RegExp(/(^|[^\\])/.source + multilineComment),
15+
lookbehind: true,
16+
greedy: true
17+
},
18+
{
19+
pattern: /(^|[^\\:])\/\/.*/,
20+
lookbehind: true,
21+
greedy: true
22+
}
23+
],
24+
'string': {
25+
pattern: /b?"(?:\\[\s\S]|[^\\"])*"|b?r(#*)"(?:[^"]|"(?!\1))*"\1/,
2226
greedy: true
2327
},
24-
{
25-
pattern: /b?"(?:\\.|[^\\\r\n"])*"/,
26-
greedy: true
27-
}
28-
],
29-
'char': {
30-
pattern: /b?'(?:\\(?:x[0-7][\da-fA-F]|u{(?:[\da-fA-F]_*){1,6}|.)|[^\\\r\n\t'])'/,
31-
alias: 'string'
32-
},
33-
'lifetime-annotation': {
34-
pattern: /'[^\s>']+/,
35-
alias: 'symbol'
36-
},
37-
'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/,
28+
'char': {
29+
pattern: /b?'(?:\\(?:x[0-7][\da-fA-F]|u{(?:[\da-fA-F]_*){1,6}|.)|[^\\\r\n\t'])'/,
30+
greedy: true,
31+
alias: 'string'
32+
},
33+
'attribute': {
34+
pattern: /#!?\[[^[\]]*\]/,
35+
greedy: true,
36+
alias: 'attr-name',
37+
inside: {
38+
'string': null // see below
39+
}
40+
},
41+
42+
// Closure params should not be confused with bitwise OR |
43+
'closure-params': {
44+
pattern: /([=(,:]\s*|\bmove\s*)\|[^|]*\||\|[^|]*\|(?=\s*(?:\{|->))/,
45+
lookbehind: true,
46+
greedy: true,
47+
inside: {
48+
'closure-punctuation': {
49+
pattern: /^\||\|$/,
50+
alias: 'punctuation'
51+
},
52+
rest: null // see below
53+
}
54+
},
3855

39-
'attribute': {
40-
pattern: /#!?\[.+?\]/,
41-
greedy: true,
42-
alias: 'attr-name'
43-
},
56+
'lifetime-annotation': {
57+
pattern: /'\w+/,
58+
alias: 'symbol'
59+
},
60+
61+
'fragment-specifier': {
62+
pattern: /(\$\w+:)[a-z]+/,
63+
lookbehind: true,
64+
alias: 'punctuation'
65+
},
66+
'variable': /\$\w+/,
67+
68+
'function-definition': {
69+
pattern: /(\bfn\s*)\w+/,
70+
lookbehind: true,
71+
alias: 'function'
72+
},
73+
'keyword': [
74+
// https://github.com/rust-lang/reference/blob/master/src/keywords.md
75+
/\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/,
76+
// primitives
77+
// https://doc.rust-lang.org/stable/rust-by-example/primitives.html
78+
/\b(?:[ui](?:8|16|32|64|128|size)|f(?:32|64)|bool|char)\b/
79+
],
80+
81+
// functions can technically start with an upper-case letter, but this will introduce a lot of false positives
82+
// and Rust's naming conventions recommend snake_case anyway.
83+
// https://doc.rust-lang.org/1.0.0/style/style/naming/README.html
84+
'function': /\b[a-z_]\w*(?=\s*(?:::\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*)?\()/,
85+
'macro': {
86+
pattern: /\w+!/,
87+
alias: 'property'
88+
},
4489

45-
'function': [
46-
/\w+(?=\s*\()/,
47-
// Macros can use parens or brackets
48-
/\w+!(?=\s*\(|\[)/
49-
],
50-
'macro-rules': {
51-
pattern: /\w+!/,
52-
alias: 'function'
53-
},
90+
// Hex, oct, bin, dec numbers with visual separators and type suffix
91+
'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/,
92+
'boolean': /\b(?:false|true)\b/,
93+
'punctuation': /->|\.\.=|\.{1,3}|::|[{}[\];(),:]/,
94+
'operator': /[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<<?=?|>>?=?|[@?]/
95+
};
5496

55-
// Hex, oct, bin, dec numbers with visual separators and type suffix
56-
'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/,
97+
Prism.languages.rust['closure-params'].inside.rest = Prism.languages.rust;
98+
Prism.languages.rust['attribute'].inside['string'] = Prism.languages.rust['string'];
5799

58-
// Closure params should not be confused with bitwise OR |
59-
'closure-params': {
60-
pattern: /\|[^|]*\|(?=\s*[{-])/,
61-
inside: {
62-
'punctuation': /[|:,]/,
63-
'operator': /[&*]/
64-
}
65-
},
66-
'punctuation': /->|\.\.=|\.{1,3}|::|[{}[\];(),:]/,
67-
'operator': /[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<<?=?|>>?=?|[@?]/
68-
};
100+
}(Prism));

components/prism-rust.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
+25-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,35 @@
11
#[test]
22
#![warn(unstable)]
3+
#[doc(hidden)]
4+
#[unstable(
5+
feature = "thread_local_internals",
6+
reason = "recently added to create a key",
7+
issue = "none"
8+
)]
39

410
----------------------------------------------------
511

612
[
7-
["attribute", "#[test]"],
8-
["attribute", "#![warn(unstable)]"]
13+
["attribute", [
14+
"#[test]"
15+
]],
16+
["attribute", [
17+
"#![warn(unstable)]"
18+
]],
19+
["attribute", [
20+
"#[doc(hidden)]"
21+
]],
22+
["attribute", [
23+
"#[unstable(\r\n\tfeature = ",
24+
["string", "\"thread_local_internals\""],
25+
",\r\n\treason = ",
26+
["string", "\"recently added to create a key\""],
27+
",\r\n\tissue = ",
28+
["string", "\"none\""],
29+
"\r\n)]"
30+
]]
931
]
1032

1133
----------------------------------------------------
1234

13-
Checks for attributes.
35+
Checks for attributes.
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
false
2+
true
3+
4+
----------------------------------------------------
5+
6+
[
7+
["boolean", "false"],
8+
["boolean", "true"]
9+
]
10+
11+
----------------------------------------------------
12+
13+
Checks for booleans.
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,134 @@
11
|x: int, y: int| -> int {}
22
|| {}
33

4+
vec1.iter().any(|&x| x == 2);
5+
foo(123, || x * x);
6+
7+
let add_one_v2 = |x: u32| -> u32 { x + 1 };
8+
let add_one_v3 = |x| { x + 1 };
9+
let add_one_v4 = |x| x + 1 ;
10+
move || println!("This is a: {}", text)
11+
412
----------------------------------------------------
513

614
[
715
["closure-params", [
8-
["punctuation", "|"],
16+
["closure-punctuation", "|"],
917
"x",
1018
["punctuation", ":"],
1119
" int",
1220
["punctuation", ","],
1321
" y",
1422
["punctuation", ":"],
1523
" int",
16-
["punctuation", "|"]
24+
["closure-punctuation", "|"]
25+
]],
26+
["punctuation", "->"],
27+
" int ",
28+
["punctuation", "{"],
29+
["punctuation", "}"],
30+
31+
["closure-params", [
32+
["closure-punctuation", "|"],
33+
["closure-punctuation", "|"]
34+
]],
35+
["punctuation", "{"],
36+
["punctuation", "}"],
37+
38+
"\r\n\r\nvec1",
39+
["punctuation", "."],
40+
["function", "iter"],
41+
["punctuation", "("],
42+
["punctuation", ")"],
43+
["punctuation", "."],
44+
["function", "any"],
45+
["punctuation", "("],
46+
["closure-params", [
47+
["closure-punctuation", "|"],
48+
["operator", "&"],
49+
"x",
50+
["closure-punctuation", "|"]
51+
]],
52+
" x ",
53+
["operator", "=="],
54+
["number", "2"],
55+
["punctuation", ")"],
56+
["punctuation", ";"],
57+
58+
["function", "foo"],
59+
["punctuation", "("],
60+
["number", "123"],
61+
["punctuation", ","],
62+
["closure-params", [
63+
["closure-punctuation", "|"],
64+
["closure-punctuation", "|"]
65+
]],
66+
" x ",
67+
["operator", "*"],
68+
" x",
69+
["punctuation", ")"],
70+
["punctuation", ";"],
71+
72+
["keyword", "let"],
73+
" add_one_v2 ",
74+
["operator", "="],
75+
["closure-params", [
76+
["closure-punctuation", "|"],
77+
"x",
78+
["punctuation", ":"],
79+
["keyword", "u32"],
80+
["closure-punctuation", "|"]
1781
]],
1882
["punctuation", "->"],
19-
" int ", ["punctuation", "{"], ["punctuation", "}"],
83+
["keyword", "u32"],
84+
["punctuation", "{"],
85+
" x ",
86+
["operator", "+"],
87+
["number", "1"],
88+
["punctuation", "}"],
89+
["punctuation", ";"],
90+
91+
["keyword", "let"],
92+
" add_one_v3 ",
93+
["operator", "="],
94+
["closure-params", [
95+
["closure-punctuation", "|"],
96+
"x",
97+
["closure-punctuation", "|"]
98+
]],
99+
["punctuation", "{"],
100+
" x ",
101+
["operator", "+"],
102+
["number", "1"],
103+
["punctuation", "}"],
104+
["punctuation", ";"],
105+
106+
["keyword", "let"],
107+
" add_one_v4 ",
108+
["operator", "="],
109+
["closure-params", [
110+
["closure-punctuation", "|"],
111+
"x",
112+
["closure-punctuation", "|"]
113+
]],
114+
" x ",
115+
["operator", "+"],
116+
["number", "1"],
117+
["punctuation", ";"],
20118

119+
["keyword", "move"],
21120
["closure-params", [
22-
["punctuation", "|"],
23-
["punctuation", "|"]
121+
["closure-punctuation", "|"],
122+
["closure-punctuation", "|"]
24123
]],
25-
["punctuation", "{"], ["punctuation", "}"]
124+
["macro", "println!"],
125+
["punctuation", "("],
126+
["string", "\"This is a: {}\""],
127+
["punctuation", ","],
128+
" text",
129+
["punctuation", ")"]
26130
]
27131

28132
----------------------------------------------------
29133

30-
Checks for closure params.
134+
Checks for closure params.

tests/languages/rust/comment_feature.test

+9-2
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,22 @@
44
/* foo
55
bar */
66

7+
/* /* */ /** */ /*! */ */
8+
/*! /* */ /** */ /*! */ */
9+
/** /* */ /** */ /*! */ */
10+
711
----------------------------------------------------
812

913
[
1014
["comment", "//"],
1115
["comment", "// foobar"],
1216
["comment", "/**/"],
13-
["comment", "/* foo\r\nbar */"]
17+
["comment", "/* foo\r\nbar */"],
18+
["comment", "/* /* */ /** */ /*! */ */"],
19+
["comment", "/*! /* */ /** */ /*! */ */"],
20+
["comment", "/** /* */ /** */ /*! */ */"]
1421
]
1522

1623
----------------------------------------------------
1724

18-
Checks for comments.
25+
Checks for comments.

0 commit comments

Comments
 (0)