1
0
Эх сурвалжийг харах

Add rust colorization support

TJ Kells 7 жил өмнө
parent
commit
38bdd17d43

+ 1 - 0
scripts/bundle.js

@@ -46,6 +46,7 @@ bundleOne('python/python');
 bundleOne('r/r');
 bundleOne('razor/razor');
 bundleOne('ruby/ruby');
+bundleOne('rust/rust');
 bundleOne('scss/scss');
 bundleOne('sql/sql');
 bundleOne('swift/swift');

+ 1 - 0
src/monaco.contribution.ts

@@ -34,6 +34,7 @@ import './razor/razor.contribution';
 import './redis/redis.contribution';
 import './redshift/redshift.contribution';
 import './ruby/ruby.contribution';
+import './rust/rust.contribution';
 import './sb/sb.contribution';
 import './scss/scss.contribution';
 import './solidity/solidity.contribution';

+ 17 - 0
src/rust/rust.contribution.ts

@@ -0,0 +1,17 @@
+/*---------------------------------------------------------------------------------------------
+ *  Copyright (c) Microsoft Corporation. All rights reserved.
+ *  Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+'use strict';
+
+import { registerLanguage } from '../_.contribution';
+
+// Allow for running under nodejs/requirejs in tests
+const _monaco: typeof monaco = (typeof monaco === 'undefined' ? (<any>self).monaco : monaco);
+
+registerLanguage({
+	id: 'rust',
+	extensions: ['.rs', '.rlib'],
+	aliases: ['Rust', 'rust'],
+	loader: () => _monaco.Promise.wrap(import('./rust'))
+});

+ 116 - 0
src/rust/rust.js

@@ -0,0 +1,116 @@
+return {
+  tokenPostfix: '.rust',
+  defaultToken: '',
+  keywords: [
+    'as', 'box', 'break', 'const', 'continue', 'crate', 'else', 'enum',
+    'extern', 'false', 'fn', 'for', 'if', 'impl', 'in', 'let', 'loop',
+    'match', 'mod', 'move', 'mut', 'pub', 'ref', 'return', 'self',
+    'static', 'struct', 'super', 'trait', 'true', 'type', 'unsafe', 'use',
+    'where', 'while', 'catch', 'default', 'union', 'static', 'abstract',
+    'alignof', 'become', 'do', 'final', 'macro', 'offsetof', 'override',
+    'priv', 'proc', 'pure', 'sizeof', 'typeof', 'unsized', 'virtual',
+    'yield',
+  ],
+
+  typeKeywords: [
+    'Self', 'm32', 'm64', 'm128', 'f80', 'f16', 'f128', 'int', 'uint',
+    'float', 'char', 'bool', 'u8', 'u16', 'u32', 'u64', 'f32', 'f64', 'i8',
+    'i16', 'i32', 'i64', 'str', 'Option', 'Either', 'c_float', 'c_double',
+    'c_void', 'FILE', 'fpos_t', 'DIR', 'dirent', 'c_char', 'c_schar',
+    'c_uchar', 'c_short', 'c_ushort', 'c_int', 'c_uint', 'c_long',
+    'c_ulong', 'size_t', 'ptrdiff_t', 'clock_t', 'time_t', 'c_longlong',
+    'c_ulonglong', 'intptr_t', 'uintptr_t', 'off_t', 'dev_t', 'ino_t',
+    'pid_t', 'mode_t', 'ssize_t',
+  ],
+
+  constants: [
+    'true', 'false', 'Some', 'None', 'Left', 'Right', 'Ok', 'Err',
+  ],
+
+  supportConstants: [
+    'EXIT_FAILURE', 'EXIT_SUCCESS', 'RAND_MAX', 'EOF', 'SEEK_SET',
+    'SEEK_CUR', 'SEEK_END', '_IOFBF', '_IONBF', '_IOLBF', 'BUFSIZ',
+    'FOPEN_MAX', 'FILENAME_MAX', 'L_tmpnam', 'TMP_MAX', 'O_RDONLY',
+    'O_WRONLY', 'O_RDWR', 'O_APPEND', 'O_CREAT', 'O_EXCL', 'O_TRUNC',
+    'S_IFIFO', 'S_IFCHR', 'S_IFBLK', 'S_IFDIR', 'S_IFREG', 'S_IFMT',
+    'S_IEXEC', 'S_IWRITE', 'S_IREAD', 'S_IRWXU', 'S_IXUSR', 'S_IWUSR',
+    'S_IRUSR', 'F_OK', 'R_OK', 'W_OK', 'X_OK', 'STDIN_FILENO',
+    'STDOUT_FILENO', 'STDERR_FILENO',
+  ],
+
+  supportMacros: [
+    'format!', 'print!', 'println!', 'panic!', 'format_args!', 'unreachable!',
+    'write!', 'writeln!'
+  ],
+
+  operators: [
+    '!', '!=', '%', '%=', '&', '&=', '&&', '*', '*=', '+', '+=', '-', '-=',
+    '->', '.', '..', '...', '/', '/=', ':', ';', '<<', '<<=', '<', '<=', '=',
+    '==', '=>', '>', '>=', '>>', '>>=', '@', '^', '^=', '|', '|=', '||', '_',
+    '?', '#'
+  ],
+
+  escapes: /\\([nrt0\"''\\]|x\h{2}|u\{\h{1,6}\})/,
+  delimiters: /[,]/,
+  symbols: /[\#\!\%\&\*\+\-\.\/\:\;\<\=\>\@\^\|_\?]+/,
+
+  tokenizer: {
+    root: [
+      [/[a-zA-Z][a-zA-Z0-9_]*!?|_[a-zA-Z0-9_]+/,
+         { cases: { '@typeKeywords': 'keyword.type',
+                    '@keywords': 'keyword',
+                    '@supportConstants': 'keyword',
+                    '@supportMacros': 'keyword',
+                    '@constants': 'keyword',
+                    '@default': 'identifier', }
+         }
+      ],
+      // Designator
+      [/\$/, 'identifier'],
+      // Lifetime annotations
+      [/'[a-zA-Z_][a-zA-Z0-9_]*(?=[^\'])/, 'identifier'],
+      // Byte literal
+      [/'\S'/, 'string.single.quote'],
+      // Strings
+      [/"/,  { token: 'string.quote', bracket: '@open', next: '@string' }],
+      {include: '@numbers'},
+      // Whitespace + comments
+      { include: '@whitespace' },
+      [/@delimiters/, { cases: { '@keywords': 'keyword',
+                                 '@default': 'delimiter' }}],
+
+      [/[{}()\[\]<>]/, '@brackets'],
+      [/@symbols/, { cases: {'@operators': 'operator', '@default'  : '' }}],
+    ],
+
+    whitespace: [
+      [/[ \t\r\n]+/, 'white'],
+      [/\/\*/, 'comment', '@comment'],
+      [/\/\/.*$/, 'comment'],
+    ],
+
+    comment: [
+      [/[^\/*]+/, 'comment' ],
+      [/\/\*/, 'comment', '@push' ],
+      ["\\*/", 'comment', '@pop'],
+      [/[\/*]/, 'comment' ]
+    ],
+
+    string: [
+      [/[^\\"]+/, 'string'],
+      [/@escapes/, 'string.escape'],
+      [/\\./, 'string.escape.invalid'],
+      [/"/, { token: 'string.quote', bracket: '@close', next: '@pop' } ]
+    ],
+    numbers: [
+      //Integer Decimal
+      [/[0-9][0-9_]*([ui](8|16|32|64)?)?/, 'number'],
+      // Float Typed
+      [/[0-9][0-9_]*(\.[0-9][0-9_]*)?([eE][+-][0-9_]+)?(f32|f64)/, 'number'],
+      // Float Exponent
+      [/[0-9][0-9_]*(\.[0-9][0-9_]*)?[eE][+-][0-9_]+(f32|f64)?/, 'number'],
+      // Float Fraction
+      [/[0-9][0-9_]*\.[0-9][0-9_]*([eE][+-][0-9_]+)?(f32|f64)?/, 'number'],
+    ]
+  }
+}

+ 134 - 0
src/rust/rust.test.ts

@@ -0,0 +1,134 @@
+/*---------------------------------------------------------------------------------------------
+ *  Copyright (c) Microsoft Corporation. All rights reserved.
+ *  Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+'use strict';
+
+import { testTokenization } from '../test/testRunner';
+
+testTokenization('rust', [
+	// String
+	[{
+		line: 'let a = "This is a string"',
+		tokens: [
+			{startIndex: 0, type: "keyword.rust"},
+			{startIndex: 3, type: "white.rust"},
+			{startIndex: 4, type: "identifier.rust"},
+			{startIndex: 5, type: "white.rust"},
+			{startIndex: 6, type: "operator.rust"},
+			{startIndex: 7, type: "white.rust"},
+			{startIndex: 8, type: "string.quote.rust"},
+			{startIndex: 9, type: "string.rust"},
+			{startIndex: 25, type: "string.quote.rust"},
+		]
+	}],
+	// Byte literal
+	[{
+		line: "let a = 'c'",
+		tokens: [
+			{startIndex: 0, type: "keyword.rust"},
+			{startIndex: 3, type: "white.rust"},
+			{startIndex: 4, type: "identifier.rust"},
+			{startIndex: 5, type: "white.rust"},
+			{startIndex: 6, type: "operator.rust"},
+			{startIndex: 7, type: "white.rust"},
+			{startIndex: 8, type: "string.byteliteral.rust"},
+		]
+	}],
+
+	// Comment
+	[{
+		line: "// This is a comment",
+		tokens: [{startIndex: 0, type: "comment.rust"},]
+	}],
+	// Block Comment
+	[{
+		line: "/* This is a block comment */",
+		tokens: [{startIndex: 0, type: "comment.rust"},]
+	}],
+	[{
+		line: "/* This is a block comment // with a comment */",
+		tokens: [{startIndex: 0, type: "comment.rust"},]
+	}],
+	// Lifetime Annotation
+	[{
+		line: 'static NAME: &\'static str = "John"',
+		tokens: [
+			{startIndex: 0, type: "keyword.rust"},
+			{startIndex: 6, type: "white.rust"},
+			{startIndex: 7, type: "identifier.rust"},
+			{startIndex: 11, type: "operator.rust"},
+			{startIndex: 12, type: "white.rust"},
+			{startIndex: 13, type: "operator.rust"},
+			{startIndex: 14, type: "identifier.rust"},
+			{startIndex: 21, type: "white.rust"},
+			{startIndex: 22, type: "keyword.type.rust"},
+			{startIndex: 25, type: "white.rust"},
+			{startIndex: 26, type: "operator.rust"},
+			{startIndex: 27, type: "white.rust"},
+			{startIndex: 28, type: "string.quote.rust"},
+			{startIndex: 29, type: "string.rust"},
+			{startIndex: 33, type: "string.quote.rust"}
+		]
+	}],
+	// Type Keywords
+	[{
+		line: 'let logical: bool = true',
+		tokens: [
+			{startIndex: 0, type: "keyword.rust"},
+			{startIndex: 3, type: "white.rust"},
+			{startIndex: 4, type: "identifier.rust"},
+			{startIndex: 11, type: "operator.rust"},
+			{startIndex: 12, type: "white.rust"},
+			{startIndex: 13, type: "keyword.type.rust"},
+			{startIndex: 17, type: "white.rust"},
+			{startIndex: 18, type: "operator.rust"},
+			{startIndex: 19, type: "white.rust"},
+			{startIndex: 20, type: "keyword.rust"},
+		]
+	}],
+	// Numbers
+		// Integer
+	[{
+		line: '1000_000_00u32',
+		tokens: [
+			{startIndex: 0, type: "number.rust"},
+		]
+	}],
+		// Float
+	[{
+		line: '1.0f32',
+		tokens: [
+			{startIndex: 0, type: "number.rust"},
+		]
+	}],
+		// Hex
+	[{
+		line: '0xFA_01i32',
+		tokens: [
+			{startIndex: 0, type: "number.rust"},
+		]
+	}],
+		// Exponent
+	[{
+		line: '1.0E-8234987_f64',
+		tokens: [
+			{startIndex: 0, type: "number.rust"},
+		]
+	}],
+		// Binary
+	[{
+		line: '0b0_1u8',
+		tokens: [
+			{startIndex: 0, type: "number.rust"},
+		]
+	}],
+		// Octal
+	[{
+		line: '0o0000_0010u64',
+		tokens: [
+			{startIndex: 0, type: "number.rust"},
+		]
+	}],
+]);

+ 164 - 0
src/rust/rust.ts

@@ -0,0 +1,164 @@
+/*---------------------------------------------------------------------------------------------
+ *  Copyright (c) Microsoft Corporation. All rights reserved.
+ *  Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+'use strict';
+
+import IRichLanguageConfiguration = monaco.languages.LanguageConfiguration;
+import ILanguage = monaco.languages.IMonarchLanguage;
+
+export const conf: IRichLanguageConfiguration = {
+	comments: {
+		lineComment: '//',
+		blockComment: ['/*', '*/'],
+	},
+	brackets: [
+		['{', '}'],
+		['[', ']'],
+		['(', ')']
+	],
+	autoClosingPairs: [
+		{ open: '[', close: ']' },
+		{ open: '{', close: '}' },
+		{ open: '(', close: ')' },
+		{ open: '\'', close: '\'', notIn: ['string', 'comment'] },
+		{ open: '"', close: '"', notIn: ['string'] },
+	],
+	surroundingPairs: [
+		{ open: '{', close: '}' },
+		{ open: '[', close: ']' },
+		{ open: '(', close: ')' },
+		{ open: '"', close: '"' },
+		{ open: '\'', close: '\'' },
+	],
+	folding: {
+		markers: {
+			start: new RegExp("^\\s*#pragma\\s+region\\b"),
+			end: new RegExp("^\\s*#pragma\\s+endregion\\b")
+		}
+	}
+};
+
+export const language = <ILanguage>{
+  tokenPostfix: '.rust',
+  defaultToken: 'invalid',
+  keywords: [
+    'as', 'box', 'break', 'const', 'continue', 'crate', 'else', 'enum',
+    'extern', 'false', 'fn', 'for', 'if', 'impl', 'in', 'let', 'loop',
+    'match', 'mod', 'move', 'mut', 'pub', 'ref', 'return', 'self',
+    'static', 'struct', 'super', 'trait', 'true', 'type', 'unsafe', 'use',
+    'where', 'while', 'catch', 'default', 'union', 'static', 'abstract',
+    'alignof', 'become', 'do', 'final', 'macro', 'offsetof', 'override',
+    'priv', 'proc', 'pure', 'sizeof', 'typeof', 'unsized', 'virtual',
+    'yield',
+  ],
+
+  typeKeywords: [
+    'Self', 'm32', 'm64', 'm128', 'f80', 'f16', 'f128', 'int', 'uint',
+    'float', 'char', 'bool', 'u8', 'u16', 'u32', 'u64', 'f32', 'f64', 'i8',
+    'i16', 'i32', 'i64', 'str', 'Option', 'Either', 'c_float', 'c_double',
+    'c_void', 'FILE', 'fpos_t', 'DIR', 'dirent', 'c_char', 'c_schar',
+    'c_uchar', 'c_short', 'c_ushort', 'c_int', 'c_uint', 'c_long',
+    'c_ulong', 'size_t', 'ptrdiff_t', 'clock_t', 'time_t', 'c_longlong',
+    'c_ulonglong', 'intptr_t', 'uintptr_t', 'off_t', 'dev_t', 'ino_t',
+    'pid_t', 'mode_t', 'ssize_t',
+  ],
+
+  constants: [
+    'true', 'false', 'Some', 'None', 'Left', 'Right', 'Ok', 'Err',
+  ],
+
+  supportConstants: [
+    'EXIT_FAILURE', 'EXIT_SUCCESS', 'RAND_MAX', 'EOF', 'SEEK_SET',
+    'SEEK_CUR', 'SEEK_END', '_IOFBF', '_IONBF', '_IOLBF', 'BUFSIZ',
+    'FOPEN_MAX', 'FILENAME_MAX', 'L_tmpnam', 'TMP_MAX', 'O_RDONLY',
+    'O_WRONLY', 'O_RDWR', 'O_APPEND', 'O_CREAT', 'O_EXCL', 'O_TRUNC',
+    'S_IFIFO', 'S_IFCHR', 'S_IFBLK', 'S_IFDIR', 'S_IFREG', 'S_IFMT',
+    'S_IEXEC', 'S_IWRITE', 'S_IREAD', 'S_IRWXU', 'S_IXUSR', 'S_IWUSR',
+    'S_IRUSR', 'F_OK', 'R_OK', 'W_OK', 'X_OK', 'STDIN_FILENO',
+    'STDOUT_FILENO', 'STDERR_FILENO',
+  ],
+
+  supportMacros: [
+    'format!', 'print!', 'println!', 'panic!', 'format_args!', 'unreachable!',
+    'write!', 'writeln!'
+  ],
+
+  operators: [
+    '!', '!=', '%', '%=', '&', '&=', '&&', '*', '*=', '+', '+=', '-', '-=',
+    '->', '.', '..', '...', '/', '/=', ':', ';', '<<', '<<=', '<', '<=', '=',
+    '==', '=>', '>', '>=', '>>', '>>=', '@', '^', '^=', '|', '|=', '||', '_',
+    '?', '#'
+  ],
+
+  escapes: /\\([nrt0\"''\\]|x\h{2}|u\{\h{1,6}\})/,
+  delimiters: /[,]/,
+  symbols: /[\#\!\%\&\*\+\-\.\/\:\;\<\=\>\@\^\|_\?]+/,
+  intSuffixes: /[iu](8|16|32|64|128|size)/,
+  floatSuffixes: /f(32|64)/,
+
+  tokenizer: {
+    root: [
+      [/[a-zA-Z][a-zA-Z0-9_]*!?|_[a-zA-Z0-9_]+/,
+         { cases: { '@typeKeywords': 'keyword.type',
+                    '@keywords': 'keyword',
+                    '@supportConstants': 'keyword',
+                    '@supportMacros': 'keyword',
+                    '@constants': 'keyword',
+                    '@default': 'identifier', }
+         }
+      ],
+      // Designator
+      [/\$/, 'identifier'],
+      // Lifetime annotations
+      [/'[a-zA-Z_][a-zA-Z0-9_]*(?=[^\'])/, 'identifier'],
+      // Byte literal
+      [/'\S'/, 'string.byteliteral'],
+      // Strings
+      [/"/,  { token: 'string.quote', bracket: '@open', next: '@string' }],
+      {include: '@numbers'},
+      // Whitespace + comments
+      { include: '@whitespace' },
+      [/@delimiters/, { cases: { '@keywords': 'keyword',
+                                 '@default': 'delimiter' }}],
+
+      [/[{}()\[\]<>]/, '@brackets'],
+      [/@symbols/, { cases: {'@operators': 'operator', '@default'  : '' }}],
+    ],
+
+    whitespace: [
+      [/[ \t\r\n]+/, 'white'],
+      [/\/\*/, 'comment', '@comment'],
+      [/\/\/.*$/, 'comment'],
+    ],
+
+    comment: [
+      [/[^\/*]+/, 'comment' ],
+      [/\/\*/, 'comment', '@push' ],
+      ["\\*/", 'comment', '@pop'],
+      [/[\/*]/, 'comment' ]
+    ],
+
+    string: [
+      [/[^\\"]+/, 'string'],
+      [/@escapes/, 'string.escape'],
+      [/\\./, 'string.escape.invalid'],
+      [/"/, { token: 'string.quote', bracket: '@close', next: '@pop' } ]
+    ],
+    numbers: [
+      //Octal
+      [/(0o[0-7_]+)(@intSuffixes)?/, {token: 'number', log: 'Octal'}],
+      //Binary
+      [/(0b[0-1_]+)(@intSuffixes)?/, {token: 'number', log: 'Binary'}],
+      //Exponent
+      [/[\d][\d_]*(\.[\d][\d_]*)?[eE][+-][\d_]+(@floatSuffixes)?/, {token: 'number', log: 'Exponent'}],
+      //Float
+      [/\b(\d\.?[\d_]*)(@floatSuffixes)?\b/,{token: 'number', log: 'Float'}],
+      //Hexadecimal
+      [/(0x[\da-fA-F]+)_?(@intSuffixes)?/, {token: 'number', log: 'Hexadecimal'}],
+      //Integer
+      [/[\d][\d_]*(@intSuffixes?)?/, {token: 'number', log: 'Integer'}],
+    ]
+  }
+};

+ 1 - 0
test/setup.js

@@ -50,6 +50,7 @@ define(['require'], function (require) {
 			'release/dev/r/r.test',
 			'release/dev/razor/razor.test',
 			'release/dev/ruby/ruby.test',
+			'release/dev/rust/rust.test',
 			'release/dev/scss/scss.test',
 			'release/dev/swift/swift.test',
 			'release/dev/sql/sql.test',