فهرست منبع

Merge remote-tracking branch 'origin/master' into pr/ALANVF/59

Alex Dima 6 سال پیش
والد
کامیت
22d999d519
65فایلهای تغییر یافته به همراه1340 افزوده شده و 247 حذف شده
  1. 1 0
      README.md
  2. 2 0
      scripts/bundle.js
  3. 4 4
      src/_.contribution.ts
  4. 1 4
      src/apex/apex.contribution.ts
  5. 1 4
      src/azcli/azcli.contribution.ts
  6. 1 4
      src/bat/bat.contribution.ts
  7. 2 6
      src/clojure/clojure.contribution.ts
  8. 90 7
      src/clojure/clojure.test.ts
  9. 38 30
      src/clojure/clojure.ts
  10. 1 4
      src/coffee/coffee.contribution.ts
  11. 2 5
      src/cpp/cpp.contribution.ts
  12. 1 4
      src/csharp/csharp.contribution.ts
  13. 1 4
      src/csp/csp.contribution.ts
  14. 1 4
      src/css/css.contribution.ts
  15. 1 4
      src/dockerfile/dockerfile.contribution.ts
  16. 1 4
      src/fsharp/fsharp.contribution.ts
  17. 1 4
      src/go/go.contribution.ts
  18. 15 0
      src/graphql/graphql.contribution.ts
  19. 143 0
      src/graphql/graphql.test.ts
  20. 141 0
      src/graphql/graphql.ts
  21. 1 4
      src/handlebars/handlebars.contribution.ts
  22. 1 4
      src/html/html.contribution.ts
  23. 1 4
      src/ini/ini.contribution.ts
  24. 1 4
      src/java/java.contribution.ts
  25. 1 4
      src/javascript/javascript.contribution.ts
  26. 15 0
      src/kotlin/kotlin.contribution.ts
  27. 671 0
      src/kotlin/kotlin.test.ts
  28. 158 0
      src/kotlin/kotlin.ts
  29. 1 4
      src/less/less.contribution.ts
  30. 1 4
      src/lua/lua.contribution.ts
  31. 1 4
      src/markdown/markdown.contribution.ts
  32. 2 0
      src/monaco.contribution.ts
  33. 1 4
      src/msdax/msdax.contribution.ts
  34. 1 4
      src/mysql/mysql.contribution.ts
  35. 1 4
      src/objective-c/objective-c.contribution.ts
  36. 1 4
      src/perl/perl.contribution.ts
  37. 1 4
      src/pgsql/pgsql.contribution.ts
  38. 1 4
      src/php/php.contribution.ts
  39. 1 4
      src/postiats/postiats.contribution.ts
  40. 1 4
      src/powerquery/powerquery.contribution.ts
  41. 1 4
      src/powershell/powershell.contribution.ts
  42. 1 4
      src/pug/pug.contribution.ts
  43. 1 4
      src/python/python.contribution.ts
  44. 1 4
      src/r/r.contribution.ts
  45. 1 4
      src/razor/razor.contribution.ts
  46. 1 4
      src/redis/redis.contribution.ts
  47. 1 4
      src/redshift/redshift.contribution.ts
  48. 1 4
      src/ruby/ruby.contribution.ts
  49. 5 1
      src/ruby/ruby.ts
  50. 1 4
      src/rust/rust.contribution.ts
  51. 1 4
      src/sb/sb.contribution.ts
  52. 1 5
      src/scheme/scheme.contribution.ts
  53. 1 4
      src/scss/scss.contribution.ts
  54. 1 5
      src/shell/shell.contribution.ts
  55. 1 4
      src/solidity/solidity.contribution.ts
  56. 1 4
      src/sql/sql.contribution.ts
  57. 1 4
      src/st/st.contribution.ts
  58. 1 4
      src/swift/swift.contribution.ts
  59. 1 3
      src/tcl/tcl.contribution.ts
  60. 1 1
      src/test/testRunner.ts
  61. 1 4
      src/typescript/typescript.contribution.ts
  62. 1 4
      src/vb/vb.contribution.ts
  63. 1 4
      src/xml/xml.contribution.ts
  64. 1 4
      src/yaml/yaml.contribution.ts
  65. 2 0
      test/setup.js

+ 1 - 0
README.md

@@ -15,6 +15,7 @@ Colorization and configuration supports for multiple languages for the Monaco Ed
 * dockerfile
 * fsharp
 * go
+* graphql
 * handlebars
 * html
 * ini

+ 2 - 0
scripts/bundle.js

@@ -35,6 +35,7 @@ bundleOne('ini/ini');
 bundleOne('pug/pug');
 bundleOne('java/java');
 bundleOne('javascript/javascript');
+bundleOne('kotlin/kotlin');
 bundleOne('less/less');
 bundleOne('lua/lua');
 bundleOne('markdown/markdown');
@@ -71,6 +72,7 @@ bundleOne('powerquery/powerquery');
 bundleOne('azcli/azcli');
 bundleOne('apex/apex');
 bundleOne('tcl/tcl');
+bundleOne('graphql/graphql');
 
 function bundleOne(moduleId, exclude) {
 	requirejs.optimize({

+ 4 - 4
src/_.contribution.ts

@@ -8,7 +8,7 @@
 const _monaco: typeof monaco = (typeof monaco === 'undefined' ? (<any>self).monaco : monaco);
 
 interface ILang extends monaco.languages.ILanguageExtensionPoint {
-	loader: () => monaco.Promise<ILangImpl>;
+	loader: () => Promise<ILangImpl>;
 }
 
 interface ILangImpl {
@@ -18,7 +18,7 @@ interface ILangImpl {
 
 let languageDefinitions: { [languageId: string]: ILang } = {};
 
-function _loadLanguage(languageId: string): monaco.Promise<void> {
+function _loadLanguage(languageId: string): Promise<void> {
 	const loader = languageDefinitions[languageId].loader;
 	return loader().then((mod) => {
 		_monaco.languages.setMonarchTokensProvider(languageId, mod.language);
@@ -26,9 +26,9 @@ function _loadLanguage(languageId: string): monaco.Promise<void> {
 	});
 }
 
-let languagePromises: { [languageId: string]: monaco.Promise<void> } = {};
+let languagePromises: { [languageId: string]: Promise<void> } = {};
 
-export function loadLanguage(languageId: string): monaco.Promise<void> {
+export function loadLanguage(languageId: string): Promise<void> {
 	if (!languagePromises[languageId]) {
 		languagePromises[languageId] = _loadLanguage(languageId);
 	}

+ 1 - 4
src/apex/apex.contribution.ts

@@ -6,13 +6,10 @@
 
 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: 'apex',
 	extensions: ['.cls'],
 	aliases: ['Apex', 'apex'],
 	mimetypes: ['text/x-apex-source', 'text/x-apex'],
-	loader: () => _monaco.Promise.wrap(import('./apex'))
+	loader: () => import('./apex')
 });

+ 1 - 4
src/azcli/azcli.contribution.ts

@@ -6,12 +6,9 @@
 
 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: 'azcli',
 	extensions: ['.azcli'],
 	aliases: ['Azure CLI', 'azcli'],
-	loader: () => _monaco.Promise.wrap(import('./azcli'))
+	loader: () => import('./azcli')
 });

+ 1 - 4
src/bat/bat.contribution.ts

@@ -6,12 +6,9 @@
 
 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: 'bat',
 	extensions: ['.bat', '.cmd'],
 	aliases: ['Batch', 'bat'],
-	loader: () => _monaco.Promise.wrap(import('./bat'))
+	loader: () => import('./bat')
 });

+ 2 - 6
src/clojure/clojure.contribution.ts

@@ -6,13 +6,9 @@
 
 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: 'clojure',
-	extensions: ['.clj', '.clojure'],
+	extensions: ['.clj', '.cljs', '.cljc', '.edn'],
 	aliases: ['clojure', 'Clojure'],
-	loader: () => _monaco.Promise.wrap(import('./clojure')),
+	loader: () => import('./clojure')
 });

+ 90 - 7
src/clojure/clojure.test.ts

@@ -754,13 +754,72 @@ testTokenization('clojure', [
 	], 'string'),
 
 	// strings
-	createTestCases([
-		'\"I\'m a little teapot.\"',
-		'\"I\'m a \\\"little\\\" teapot.\"',
-		'\"I\'m',      // this is
-		'a little',    // a multi-line
-		'teapot.\"'    // string
-	], 'string'),
+	[
+		{
+			line: '"I\'m a little teapot."',
+			tokens: [
+				{startIndex: 0, type: 'string.clj'},
+			]
+		},
+		{
+			line: '"I\'m a \\"little\\" teapot."',
+			tokens: [
+				{startIndex: 0, type: 'string.clj'},
+				{startIndex: 7, type: 'string.escape.clj'},
+				{startIndex: 9, type: 'string.clj'},
+				{startIndex: 15, type: 'string.escape.clj'},
+				{startIndex: 17, type: 'string.clj'},
+			]
+		}
+	],
+
+	// multi-line strings
+	[
+		{
+			line: '"I\'m',
+			tokens: [
+				{startIndex: 0, type: 'string.clj'},
+			]
+		},
+		{
+			line: '\\"a little\\"',
+			tokens: [
+				{startIndex: 0, type: 'string.escape.clj'},
+				{startIndex: 2, type: 'string.clj'},
+				{startIndex: 10, type: 'string.escape.clj'},
+			]
+		},
+		{
+			line: 'teapot."',
+			tokens: [
+				{startIndex: 0, type: 'string.clj'},
+			]
+		}
+	],
+
+	// strings with other escapes in them (\" \' \\ \b \f \n \r \t)
+	[{
+		line: '"the escape \\" \\\' \\\\ \\b \\f \\n \\r \\t characters"',
+		tokens: [
+			{startIndex: 0, type: 'string.clj'},
+			{startIndex: 12, type: 'string.escape.clj'},
+			{startIndex: 14, type: 'string.clj'},
+			{startIndex: 15, type: 'string.escape.clj'},
+			{startIndex: 17, type: 'string.clj'},
+			{startIndex: 18, type: 'string.escape.clj'},
+			{startIndex: 20, type: 'string.clj'},
+			{startIndex: 21, type: 'string.escape.clj'},
+			{startIndex: 23, type: 'string.clj'},
+			{startIndex: 24, type: 'string.escape.clj'},
+			{startIndex: 26, type: 'string.clj'},
+			{startIndex: 27, type: 'string.escape.clj'},
+			{startIndex: 29, type: 'string.clj'},
+			{startIndex: 30, type: 'string.escape.clj'},
+			{startIndex: 32, type: 'string.clj'},
+			{startIndex: 33, type: 'string.escape.clj'},
+			{startIndex: 35, type: 'string.clj'},
+		]
+	}],
 
 	// comments
 	createTestCases([
@@ -792,6 +851,30 @@ testTokenization('clojure', [
 				{startIndex: 0, type: 'comment.clj'},
 			],
 		},
+		{
+			line: '(comments foo bar)',
+			tokens: [
+				{startIndex: 0, type: 'delimiter.parenthesis.clj'},
+				{startIndex: 1, type: 'identifier.clj'},
+				{startIndex: 9, type: 'white.clj'},
+				{startIndex: 10, type: 'identifier.clj'},
+				{startIndex: 13, type: 'white.clj'},
+				{startIndex: 14, type: 'identifier.clj'},
+				{startIndex: 17, type: 'delimiter.parenthesis.clj'},
+			]
+		},
+		{
+			line: '(comment6 foo bar)',
+			tokens: [
+				{startIndex: 0, type: 'delimiter.parenthesis.clj'},
+				{startIndex: 1, type: 'identifier.clj'},
+				{startIndex: 9, type: 'white.clj'},
+				{startIndex: 10, type: 'identifier.clj'},
+				{startIndex: 13, type: 'white.clj'},
+				{startIndex: 14, type: 'identifier.clj'},
+				{startIndex: 17, type: 'delimiter.parenthesis.clj'},
+			]
+		},
 		{
 			line: '(comment foo',
 			tokens: [

+ 38 - 30
src/clojure/clojure.ts

@@ -13,20 +13,24 @@ export const conf: IRichLanguageConfiguration = {
 		lineComment: ';;',
 	},
 
-	brackets: [['(', ')'], ['[', ']'], ['{', '}']],
+	brackets: [
+		['[', ']'],
+		['(', ')'],
+		['{', '}']
+	],
 
 	autoClosingPairs: [
-		{open: '(', close: ')'},
 		{open: '[', close: ']'},
-		{open: '{', close: '}'},
 		{open: '"', close: '"'},
+		{open: '(', close: ')'},
+		{open: '{', close: '}'},
 	],
 
 	surroundingPairs: [
-		{open: '(', close: ')'},
 		{open: '[', close: ']'},
-		{open: '{', close: '}'},
 		{open: '"', close: '"'},
+		{open: '(', close: ')'},
+		{open: '{', close: '}'},
 	],
 };
 
@@ -36,11 +40,26 @@ export const language = <ILanguage>{
 	tokenPostfix: '.clj',
 
 	brackets: [
+		{open: '[', close: ']', token: 'delimiter.square'},
 		{open: '(', close: ')', token: 'delimiter.parenthesis'},
 		{open: '{', close: '}', token: 'delimiter.curly'},
-		{open: '[', close: ']', token: 'delimiter.square'},
 	],
 
+	constants: ['true', 'false', 'nil'],
+
+	// delimiters: /[\\\[\]\s"#'(),;@^`{}~]|$/,
+
+	numbers: /^(?:[+\-]?\d+(?:(?:N|(?:[eE][+\-]?\d+))|(?:\.?\d*(?:M|(?:[eE][+\-]?\d+))?)|\/\d+|[xX][0-9a-fA-F]+|r[0-9a-zA-Z]+)?(?=[\\\[\]\s"#'(),;@^`{}~]|$))/,
+
+	characters: /^(?:\\(?:backspace|formfeed|newline|return|space|tab|o[0-7]{3}|u[0-9A-Fa-f]{4}|x[0-9A-Fa-f]{4}|.)?(?=[\\\[\]\s"(),;@^`{}~]|$))/,
+
+	escapes: /^\\(?:["'\\bfnrt]|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,
+
+	// simple-namespace := /^[^\\\/\[\]\d\s"#'(),;@^`{}~][^\\\[\]\s"(),;@^`{}~]*/
+	// simple-symbol    := /^(?:\/|[^\\\/\[\]\d\s"#'(),;@^`{}~][^\\\[\]\s"(),;@^`{}~]*)/
+	// qualified-symbol := (<simple-namespace>(<.><simple-namespace>)*</>)?<simple-symbol>
+	qualifiedSymbols: /^(?:(?:[^\\\/\[\]\d\s"#'(),;@^`{}~][^\\\[\]\s"(),;@^`{}~]*(?:\.[^\\\/\[\]\d\s"#'(),;@^`{}~][^\\\[\]\s"(),;@^`{}~]*)*\/)?(?:\/|[^\\\/\[\]\d\s"#'(),;@^`{}~][^\\\[\]\s"(),;@^`{}~]*)*(?=[\\\[\]\s"(),;@^`{}~]|$))/,
+
 	specialForms: [
 		'.',
 		'catch',
@@ -712,14 +731,6 @@ export const language = <ILanguage>{
 		'zipmap',
 	],
 
-	constants: ['true', 'false', 'nil'],
-
-	symbolCharacter: /[!#'*+\-.\/:<=>?_\w\xa1-\uffff]/,
-
-	numbers: /[+\-]?\d+(?:(?:N|(?:[eE][+\-]?\d+))|(?:\.?\d*(?:M|(?:[eE][+\-]?\d+))?)|\/\d+|[xX][0-9a-fA-F]+|r[0-9a-zA-Z]+)?/,
-
-	characters: /\\(?:backspace|formfeed|newline|return|space|tab|x[0-9A-Fa-f]{4}|u[0-9A-Fa-f]{4}|o[0-7]{3}|@symbolCharacter|[\\"()\[\]{}])/,
-
 	tokenizer: {
 		root: [
 			// whitespaces and comments
@@ -743,32 +754,29 @@ export const language = <ILanguage>{
 			// reader macro characters
 			[/[#'@^`~]/, 'meta'],
 
-			// keywords
-			[/:@symbolCharacter+/, 'constant'],
-
 			// symbols
-			[/@symbolCharacter+/, {
-				cases: {
-					'@specialForms': 'keyword',
-					'@coreSymbols': 'keyword',
-					'@constants': 'constant',
-					'@default': 'identifier',
+			[/@qualifiedSymbols/, {
+					cases: {
+						'^:.+$': 'constant',  // Clojure keywords (e.g., `:foo/bar`)
+						'@specialForms': 'keyword',
+						'@coreSymbols': 'keyword',
+						'@constants': 'constant',
+						'@default': 'identifier',
+					},
 				},
-			},
 			],
-
 		],
 
 		whitespace: [
 			[/\s+/, 'white'],
 			[/;.*$/, 'comment'],
-			[/\(comment/, 'comment', '@comment'],
+			[/\(comment\b/, 'comment', '@comment'],
 		],
 
 		comment: [
 			[/\(/, 'comment', '@push'],
 			[/\)/, 'comment', '@pop'],
-			[/[^)]/, 'comment'],
+			[/[^()]/, 'comment'],
 		],
 
 		string: [
@@ -776,9 +784,9 @@ export const language = <ILanguage>{
 		],
 
 		multiLineString: [
-			[/[^\\"]+/, 'string'],
-			[/@characters/, 'string'],
-			[/"/, 'string', '@pop']
+			[/"/, 'string', '@popall'],
+			[/@escapes/, 'string.escape'],
+			[/./, 'string']
 		],
 	},
 };

+ 1 - 4
src/coffee/coffee.contribution.ts

@@ -6,13 +6,10 @@
 
 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: 'coffeescript',
 	extensions: ['.coffee'],
 	aliases: ['CoffeeScript', 'coffeescript', 'coffee'],
 	mimetypes: ['text/x-coffeescript', 'text/coffeescript'],
-	loader: () => _monaco.Promise.wrap(import('./coffee'))
+	loader: () => import('./coffee')
 });

+ 2 - 5
src/cpp/cpp.contribution.ts

@@ -6,18 +6,15 @@
 
 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: 'c',
 	extensions: ['.c', '.h'],
 	aliases: ['C', 'c'],
-	loader: () => _monaco.Promise.wrap(import('./cpp'))
+	loader: () => import('./cpp')
 });
 registerLanguage({
 	id: 'cpp',
 	extensions: ['.cpp', '.cc', '.cxx', '.hpp', '.hh', '.hxx'],
 	aliases: ['C++', 'Cpp', 'cpp'],
-	loader: () => _monaco.Promise.wrap(import('./cpp'))
+	loader: () => import('./cpp')
 });

+ 1 - 4
src/csharp/csharp.contribution.ts

@@ -6,12 +6,9 @@
 
 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: 'csharp',
 	extensions: ['.cs', '.csx', '.cake'],
 	aliases: ['C#', 'csharp'],
-	loader: () => _monaco.Promise.wrap(import('./csharp'))
+	loader: () => import('./csharp')
 });

+ 1 - 4
src/csp/csp.contribution.ts

@@ -6,12 +6,9 @@
 
 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: 'csp',
 	extensions: [],
 	aliases: ['CSP', 'csp'],
-	loader: () => _monaco.Promise.wrap(import('./csp'))
+	loader: () => import('./csp')
 });

+ 1 - 4
src/css/css.contribution.ts

@@ -6,13 +6,10 @@
 
 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: 'css',
 	extensions: ['.css'],
 	aliases: ['CSS', 'css'],
 	mimetypes: ['text/css'],
-	loader: () => _monaco.Promise.wrap(import('./css'))
+	loader: () => import('./css')
 });

+ 1 - 4
src/dockerfile/dockerfile.contribution.ts

@@ -6,13 +6,10 @@
 
 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: 'dockerfile',
 	extensions: ['.dockerfile'],
 	filenames: ['Dockerfile'],
 	aliases: ['Dockerfile'],
-	loader: () => _monaco.Promise.wrap(import('./dockerfile'))
+	loader: () => import('./dockerfile')
 });

+ 1 - 4
src/fsharp/fsharp.contribution.ts

@@ -6,12 +6,9 @@
 
 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: 'fsharp',
 	extensions: ['.fs', '.fsi', '.ml', '.mli', '.fsx', '.fsscript'],
 	aliases: ['F#', 'FSharp', 'fsharp'],
-	loader: () => _monaco.Promise.wrap(import('./fsharp'))
+	loader: () => import('./fsharp')
 });

+ 1 - 4
src/go/go.contribution.ts

@@ -6,12 +6,9 @@
 
 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: 'go',
 	extensions: ['.go'],
 	aliases: ['Go'],
-	loader: () => _monaco.Promise.wrap(import('./go'))
+	loader: () => import('./go')
 });

+ 15 - 0
src/graphql/graphql.contribution.ts

@@ -0,0 +1,15 @@
+/*---------------------------------------------------------------------------------------------
+ *  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';
+
+registerLanguage({
+	id: 'graphql',
+	extensions: ['.graphql', '.gql'],
+	aliases: ['GraphQL', 'graphql', 'gql'],
+	mimetypes: ['application/graphql'],
+	loader: () => import('./graphql')
+});

+ 143 - 0
src/graphql/graphql.test.ts

@@ -0,0 +1,143 @@
+/*---------------------------------------------------------------------------------------------
+ *  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('graphql', [
+	// Keywords
+	[{
+		line: 'scalar Date',
+		tokens: [
+			{ startIndex: 0, type: 'keyword.gql' },
+			{ startIndex: 6, type: '' },
+			{ startIndex: 7, type: 'type.identifier.gql' },
+		]
+	}],
+
+	// Root schema definition
+	[{
+		line: 'schema { query: Query, mutation: Mutation subscription: Subscription }',
+		tokens: [
+			{ startIndex: 0, type: "keyword.gql" },
+			{ startIndex: 6, type: "" },
+			{ startIndex: 7, type: "delimiter.curly.gql" },
+			{ startIndex: 8, type: "" },
+			{ startIndex: 9, type: "keyword.gql" }, // this should be identifier
+			{ startIndex: 14, type: "operator.gql" },
+			{ startIndex: 15, type: "" },
+			{ startIndex: 16, type: "type.identifier.gql" },
+			{ startIndex: 21, type: "delimiter.gql" },
+			{ startIndex: 22, type: "" },
+			{ startIndex: 23, type: "keyword.gql" }, // this should be identifier
+			{ startIndex: 31, type: "operator.gql" },
+			{ startIndex: 32, type: "" },
+			{ startIndex: 33, type: "type.identifier.gql" },
+			{ startIndex: 41, type: "" },
+			{ startIndex: 42, type: "keyword.gql" }, // this should be identifier
+			{ startIndex: 54, type: "operator.gql" },
+			{ startIndex: 55, type: "" },
+			{ startIndex: 56, type: "type.identifier.gql" },
+			{ startIndex: 68, type: "" },
+			{ startIndex: 69, type: "delimiter.curly.gql" },
+		]
+	}],
+
+	[{
+		line: `query testQuery($intValue:Int=3){value(arg:{string:"string" int:$intValue}){field1 field2}}`,
+		tokens: [
+			{ startIndex: 0, type: "keyword.gql" },                 // 'query'
+			{ startIndex: 5, type: "" },                            // ' '
+			{ startIndex: 6, type: "identifier.gql" },              // 'testQuery'
+			{ startIndex: 15, type: "delimiter.parenthesis.gql" },  // '('
+			{ startIndex: 16, type: "identifier.gql" },             // '$intValue'
+			{ startIndex: 25, type: "operator.gql" },               // ':'
+			{ startIndex: 26, type: "keyword.gql" },                // 'Int'
+			{ startIndex: 29, type: "operator.gql" },               // '='
+			{ startIndex: 30, type: "number.gql" },                 // '3'
+			{ startIndex: 31, type: "delimiter.parenthesis.gql" },  // ')'
+			{ startIndex: 32, type: "delimiter.curly.gql" },        // '{'
+			{ startIndex: 33, type: "identifier.gql" },             // 'value'
+			{ startIndex: 38, type: "delimiter.parenthesis.gql" },  // '('
+			{ startIndex: 39, type: "identifier.gql" },             // 'arg'
+			{ startIndex: 42, type: "operator.gql" },               // ':'
+			{ startIndex: 43, type: "delimiter.curly.gql" },        // '{'
+			{ startIndex: 44, type: "identifier.gql" },             // 'string'
+			{ startIndex: 50, type: "operator.gql" },               // ':'
+			{ startIndex: 51, type: "string.quote.gql" },           // '"'
+			{ startIndex: 52, type: "string.gql" },                 // 'string'
+			{ startIndex: 58, type: "string.quote.gql" },           // '"'
+			{ startIndex: 59, type: "" },                           // ' '
+			{ startIndex: 60, type: "identifier.gql" },             // 'int'
+			{ startIndex: 63, type: "operator.gql" },               // ':'
+			{ startIndex: 64, type: "identifier.gql" },             // '$intValue'
+			{ startIndex: 73, type: "delimiter.curly.gql" },        // '}'
+			{ startIndex: 74, type: "delimiter.parenthesis.gql" },  // ')'
+			{ startIndex: 75, type: "delimiter.curly.gql" },        // '{'
+			{ startIndex: 76, type: "identifier.gql" },             // 'field1'
+			{ startIndex: 82, type: "" },                           // ' '
+			{ startIndex: 83, type: "identifier.gql" },             // 'field2'
+			{ startIndex: 89, type: "delimiter.curly.gql" },        // '}}'
+		],
+	}],
+
+	// More complex test:
+	//   """
+	//   Node interface
+	//   - allows (re)fetch arbitrary entity only by ID
+	//   """
+	//   interface Node {
+	//     id: ID!
+	//   }
+	[
+		{
+			line: '"""',
+			tokens: [
+				{ startIndex: 0, type: "string.gql" }
+			],
+		},
+		{
+			line: 'This is MarkDown',
+			tokens: [
+				{ startIndex: 0, type: "" }
+			],
+		},
+		{
+			line: '"""',
+			tokens: [
+				{ startIndex: 0, type: "string.gql" }
+			],
+		},
+		{
+			line: 'interface Node {',
+			tokens: [
+				{ startIndex: 0, type: "keyword.gql" },
+				{ startIndex: 9, type: "" },
+				{ startIndex: 10, type: "type.identifier.gql" },
+				{ startIndex: 14, type: "" },
+				{ startIndex: 15, type: "delimiter.curly.gql" },
+			],
+		},
+		{
+			line: '  id: ID!',
+			tokens: [
+				{ startIndex: 0, type: "" },
+				{ startIndex: 2, type: "identifier.gql" },
+				{ startIndex: 4, type: "operator.gql" },
+				{ startIndex: 5, type: "" },
+				{ startIndex: 6, type: "keyword.gql" },
+				{ startIndex: 8, type: "operator.gql" },
+			],
+		},
+		{
+			line: '}',
+			tokens: [
+				{ startIndex: 0, type: "delimiter.curly.gql", },
+			],
+		},
+	]
+
+]);

+ 141 - 0
src/graphql/graphql.ts

@@ -0,0 +1,141 @@
+/*---------------------------------------------------------------------------------------------
+ *  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: '#'
+	},
+	brackets: [
+		['{', '}'],
+		['[', ']'],
+		['(', ')']
+	],
+	autoClosingPairs: [
+		{ open: '{', close: '}' },
+		{ open: '[', close: ']' },
+		{ open: '(', close: ')' },
+		{ open: '"""', close: '"""', notIn: ['string', 'comment'] },
+		{ open: '"', close: '"', notIn: ['string', 'comment'] },
+	],
+	surroundingPairs: [
+		{ open: '{', close: '}' },
+		{ open: '[', close: ']' },
+		{ open: '(', close: ')' },
+		{ open: '"""', close: '"""' },
+		{ open: '"', close: '"' },
+	],
+	folding: {
+		offSide: true
+	}
+};
+
+export const language = <ILanguage>{
+	// Set defaultToken to invalid to see what you do not tokenize yet
+	defaultToken: 'invalid',
+	tokenPostfix: '.gql',
+
+	keywords: [
+		'null', 'true', 'false',
+		'query', 'mutation', 'subscription',
+		'extend', 'schema', 'directive',
+		'scalar', 'type', 'interface', 'union', 'enum', 'input', 'implements',
+		'fragment', 'on',
+	],
+
+	typeKeywords: ['Int', 'Float', 'String', 'Boolean', 'ID'],
+
+	directiveLocations: [
+		'SCHEMA', 'SCALAR', 'OBJECT', 'FIELD_DEFINITION', 'ARGUMENT_DEFINITION',
+		'INTERFACE', 'UNION', 'ENUM', 'ENUM_VALUE', 'INPUT_OBJECT', 'INPUT_FIELD_DEFINITION',
+		'QUERY', 'MUTATION', 'SUBSCRIPTION', 'FIELD', 'FRAGMENT_DEFINITION',
+		'FRAGMENT_SPREAD', 'INLINE_FRAGMENT', 'VARIABLE_DEFINITION',
+	],
+
+	operators: ['=', '!', '?', ':', '&', '|'],
+
+	// we include these common regular expressions
+	symbols: /[=!?:&|]+/,
+
+	// https://facebook.github.io/graphql/draft/#sec-String-Value
+	escapes: /\\(?:["\\\/bfnrt]|u[0-9A-Fa-f]{4})/,
+
+	// The main tokenizer for our languages
+	tokenizer: {
+		root: [
+			// identifiers and keywords
+			[
+				/[a-z_$][\w$]*/,
+				{
+					cases: {
+						'@keywords': 'keyword',
+						'@default': 'identifier',
+					},
+				},
+			],
+			[
+				/[A-Z][\w\$]*/,
+				{
+					cases: {
+						'@typeKeywords': 'keyword',
+						'@default': 'type.identifier',
+					},
+				},
+			], // to show class names nicely
+
+			// whitespace
+			{ include: '@whitespace' },
+
+			// delimiters and operators
+			[/[{}()\[\]]/, '@brackets'],
+			[
+				/@symbols/,
+				{ cases: { '@operators': 'operator', '@default': '' } },
+			],
+
+			// @ annotations.
+			// As an example, we emit a debugging log message on these tokens.
+			// Note: message are supressed during the first load -- change some lines to see them.
+			[
+				/@\s*[a-zA-Z_\$][\w\$]*/,
+				{ token: 'annotation', log: 'annotation token: $0' },
+			],
+
+			// numbers
+			[/\d*\.\d+([eE][\-+]?\d+)?/, 'number.float'],
+			[/0[xX][0-9a-fA-F]+/, 'number.hex'],
+			[/\d+/, 'number'],
+
+			// delimiter: after number because of .\d floats
+			[/[;,.]/, 'delimiter'],
+
+			[/"""/,
+				{ token: 'string', next: '@mlstring', nextEmbedded: 'markdown' }
+			],
+
+			// strings
+			[/"([^"\\]|\\.)*$/, 'string.invalid'], // non-teminated string
+			[/"/, { token: 'string.quote', bracket: '@open', next: '@string' }],
+		],
+
+		mlstring: [
+			[/[^"]+/, 'string'],
+			['"""', { token: 'string', next: '@pop', nextEmbedded: '@pop' }]
+		],
+
+		string: [
+			[/[^\\"]+/, 'string'],
+			[/@escapes/, 'string.escape'],
+			[/\\./, 'string.escape.invalid'],
+			[/"/, { token: 'string.quote', bracket: '@close', next: '@pop' }],
+		],
+
+		whitespace: [[/[ \t\r\n]+/, ''], [/#.*$/, 'comment']],
+	},
+};

+ 1 - 4
src/handlebars/handlebars.contribution.ts

@@ -6,13 +6,10 @@
 
 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: 'handlebars',
 	extensions: ['.handlebars', '.hbs'],
 	aliases: ['Handlebars', 'handlebars'],
 	mimetypes: ['text/x-handlebars-template'],
-	loader: () => _monaco.Promise.wrap(import('./handlebars'))
+	loader: () => import('./handlebars')
 });

+ 1 - 4
src/html/html.contribution.ts

@@ -6,13 +6,10 @@
 
 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: 'html',
 	extensions: ['.html', '.htm', '.shtml', '.xhtml', '.mdoc', '.jsp', '.asp', '.aspx', '.jshtm'],
 	aliases: ['HTML', 'htm', 'html', 'xhtml'],
 	mimetypes: ['text/html', 'text/x-jshtm', 'text/template', 'text/ng-template'],
-	loader: () => _monaco.Promise.wrap(import('./html'))
+	loader: () => import('./html')
 });

+ 1 - 4
src/ini/ini.contribution.ts

@@ -6,13 +6,10 @@
 
 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: 'ini',
 	extensions: ['.ini', '.properties', '.gitconfig'],
 	filenames: ['config', '.gitattributes', '.gitconfig', '.editorconfig'],
 	aliases: ['Ini', 'ini'],
-	loader: () => _monaco.Promise.wrap(import('./ini'))
+	loader: () => import('./ini')
 });

+ 1 - 4
src/java/java.contribution.ts

@@ -6,13 +6,10 @@
 
 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: 'java',
 	extensions: ['.java', '.jav'],
 	aliases: ['Java', 'java'],
 	mimetypes: ['text/x-java-source', 'text/x-java'],
-	loader: () => _monaco.Promise.wrap(import('./java'))
+	loader: () => import('./java')
 });

+ 1 - 4
src/javascript/javascript.contribution.ts

@@ -6,9 +6,6 @@
 
 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: 'javascript',
 	extensions: ['.js', '.es6', '.jsx'],
@@ -16,5 +13,5 @@ registerLanguage({
 	filenames: ['jakefile'],
 	aliases: ['JavaScript', 'javascript', 'js'],
 	mimetypes: ['text/javascript'],
-	loader: () => _monaco.Promise.wrap(import('./javascript'))
+	loader: () => import('./javascript')
 });

+ 15 - 0
src/kotlin/kotlin.contribution.ts

@@ -0,0 +1,15 @@
+/*---------------------------------------------------------------------------------------------
+ *  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';
+
+registerLanguage({
+	id: 'kotlin',
+	extensions: ['.kt'],
+	aliases: ['Kotlin', 'kotlin'],
+	mimetypes: ['text/x-kotlin-source', 'text/x-kotlin'],
+	loader: () => import('./kotlin')
+});

+ 671 - 0
src/kotlin/kotlin.test.ts

@@ -0,0 +1,671 @@
+/*---------------------------------------------------------------------------------------------
+ *  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('kotlin', [
+	// inline reified function
+	[{
+		line: 'inline fun <reified T : Any> foo()',
+		tokens: [
+			{ startIndex: 0, type: 'keyword.inline.kt' },
+			{ startIndex: 6, type: '' },
+			{ startIndex: 7, type: 'keyword.fun.kt' },
+			{ startIndex: 10, type: '' },
+			{ startIndex: 11, type: 'delimiter.angle.kt' },
+			{ startIndex: 12, type: 'keyword.reified.kt' },
+			{ startIndex: 19, type: '' },
+			{ startIndex: 20, type: 'type.identifier.kt' },
+			{ startIndex: 21, type: '' },
+			{ startIndex: 22, type: 'delimiter.kt' },
+			{ startIndex: 23, type: '' },
+			{ startIndex: 24, type: 'type.identifier.kt' },
+			{ startIndex: 27, type: 'delimiter.angle.kt' },
+			{ startIndex: 28, type: '' },
+			{ startIndex: 29, type: 'identifier.kt' },
+			{ startIndex: 32, type: 'delimiter.parenthesis.kt' },
+		]
+	}],
+
+	// Val declaration and assignment
+	[{
+		line: 'val x: X=5',
+		tokens: [
+			{ startIndex: 0, type: 'keyword.val.kt' },
+			{ startIndex: 3, type: '' },
+			{ startIndex: 4, type: 'identifier.kt' },
+			{ startIndex: 5, type: 'delimiter.kt' },
+			{ startIndex: 6, type: '' },
+			{ startIndex: 7, type: 'type.identifier.kt' },
+			{ startIndex: 8, type: 'delimiter.kt' },
+			{ startIndex: 9, type: 'number.kt' },
+		]
+	}],
+
+	// Comments - single line
+	[{
+		line: '//',
+		tokens: [
+			{ startIndex: 0, type: 'comment.kt' }
+		]
+	}],
+
+	[{
+		line: '    // a comment',
+		tokens: [
+			{ startIndex: 0, type: '' },
+			{ startIndex: 4, type: 'comment.kt' }
+		]
+	}],
+
+	// Broken nested tokens due to invalid comment tokenization
+	[{
+		line: '/* //*/ a',
+		tokens: [
+			{ startIndex: 0, type: 'comment.kt' },
+			{ startIndex: 7, type: '' },
+			{ startIndex: 8, type: 'identifier.kt' }
+		]
+	}],
+
+	[{
+		line: '// a comment',
+		tokens: [
+			{ startIndex: 0, type: 'comment.kt' }
+		]
+	}],
+
+	[{
+		line: '//sticky comment',
+		tokens: [
+			{ startIndex: 0, type: 'comment.kt' }
+		]
+	}],
+
+	[{
+		line: '/almost a comment',
+		tokens: [
+			{ startIndex: 0, type: 'delimiter.kt' },
+			{ startIndex: 1, type: 'identifier.kt' },
+			{ startIndex: 7, type: '' },
+			{ startIndex: 8, type: 'identifier.kt' },
+			{ startIndex: 9, type: '' },
+			{ startIndex: 10, type: 'identifier.kt' }
+		]
+	}],
+
+	[{
+		line: '1 / 2; /* comment',
+		tokens: [
+			{ startIndex: 0, type: 'number.kt' },
+			{ startIndex: 1, type: '' },
+			{ startIndex: 2, type: 'delimiter.kt' },
+			{ startIndex: 3, type: '' },
+			{ startIndex: 4, type: 'number.kt' },
+			{ startIndex: 5, type: 'delimiter.kt' },
+			{ startIndex: 6, type: '' },
+			{ startIndex: 7, type: 'comment.kt' }
+		]
+	}],
+
+	// [{
+	// 	line: 'var x = 1 // my comment // is a nice one',
+	// 	tokens: [
+	// 		{ startIndex: 0, type: 'keyword.var.kt' },
+	// 		{ startIndex: 3, type: '' },
+	// 		{ startIndex: 4, type: 'identifier.kt' },
+	// 		{ startIndex: 5, type: '' },
+	// 		{ startIndex: 6, type: 'delimiter.kt' },
+	// 		{ startIndex: 7, type: '' },
+	// 		{ startIndex: 8, type: 'number.kt' },
+	// 		{ startIndex: 9, type: '' },
+	// 		{ startIndex: 10, type: 'comment.kt' },
+	// 		{ startIndex: 12, type: '' },
+	// 		{ startIndex: 13, type: 'comment.kt' }
+	// 	]
+	// }],
+
+	// Comments - range comment, single line
+	[{
+		line: '/* a simple comment */',
+		tokens: [
+			{ startIndex: 0, type: 'comment.kt' }
+		]
+	}],
+
+	[{
+		line: 'var x = /* a simple comment */ 1',
+		tokens: [
+			{ startIndex: 0, type: 'keyword.var.kt' },
+			{ startIndex: 3, type: '' },
+			{ startIndex: 4, type: 'identifier.kt' },
+			{ startIndex: 5, type: '' },
+			{ startIndex: 6, type: 'delimiter.kt' },
+			{ startIndex: 7, type: '' },
+			{ startIndex: 8, type: 'comment.kt' },
+			{ startIndex: 30, type: '' },
+			{ startIndex: 31, type: 'number.kt' },
+		]
+	}],
+
+	[{
+		line: 'var x = /* comment */ 1; */',
+		tokens: [
+			{ startIndex: 0, type: 'keyword.var.kt' },
+			{ startIndex: 3, type: '' },
+			{ startIndex: 4, type: 'identifier.kt' },
+			{ startIndex: 5, type: '' },
+			{ startIndex: 6, type: 'delimiter.kt' },
+			{ startIndex: 7, type: '' },
+			{ startIndex: 8, type: 'comment.kt' },
+			{ startIndex: 21, type: '' },
+			{ startIndex: 22, type: 'number.kt' },
+			{ startIndex: 23, type: 'delimiter.kt' },
+			{ startIndex: 24, type: '' }
+		]
+	}],
+
+	[{
+		line: 'x = /**/',
+		tokens: [
+			{ startIndex: 0, type: 'identifier.kt' },
+			{ startIndex: 1, type: '' },
+			{ startIndex: 2, type: 'delimiter.kt' },
+			{ startIndex: 3, type: '' },
+			{ startIndex: 4, type: 'comment.kt' },
+		]
+	}],
+
+	[{
+		line: 'var x = /** start a Java Doc comment',
+		tokens: [
+			{ startIndex: 0, type: 'keyword.var.kt' },
+			{ startIndex: 3, type: '' },
+			{ startIndex: 4, type: 'identifier.kt' },
+			{ startIndex: 5, type: '' },
+			{ startIndex: 6, type: 'delimiter.kt' },
+			{ startIndex: 7, type: '' },
+			{ startIndex: 8, type: 'comment.doc.kt' }
+		]
+	}, {
+		line: ' a ',
+		tokens: [
+			{ startIndex: 0, type: 'comment.doc.kt' }
+		]
+	}, {
+		line: 'and end it */ 2',
+		tokens: [
+			{ startIndex: 0, type: 'comment.doc.kt' },
+			{ startIndex: 13, type: '' },
+			{ startIndex: 14, type: 'number.kt' },
+		]
+	}],
+
+	[{
+		line: '/** start of Java Doc',
+		tokens: [
+			{ startIndex: 0, type: 'comment.doc.kt' }
+		]
+	}, {
+		line: 'a comment between without a star',
+		tokens: [
+			{ startIndex: 0, type: 'comment.doc.kt' }
+		]
+	}, {
+		line: 'end of multiline comment*/',
+		tokens: [
+			{ startIndex: 0, type: 'comment.doc.kt' }
+		]
+	}],
+
+	// Keywords
+	[{
+		line: 'package test class Program { fun main(vararg args: String) {} } }',
+		tokens: [
+			{ startIndex: 0, type: 'keyword.package.kt' },
+			{ startIndex: 7, type: '' },
+			{ startIndex: 8, type: 'identifier.kt' },
+			{ startIndex: 12, type: '' },
+			{ startIndex: 13, type: 'keyword.class.kt' },
+			{ startIndex: 18, type: '' },
+			{ startIndex: 19, type: 'type.identifier.kt' },
+			{ startIndex: 26, type: '' },
+			{ startIndex: 27, type: 'delimiter.curly.kt' },
+			{ startIndex: 28, type: '' },
+			{ startIndex: 29, type: 'keyword.fun.kt' },
+			{ startIndex: 32, type: '' },
+			{ startIndex: 33, type: 'identifier.kt' },
+			{ startIndex: 37, type: 'delimiter.parenthesis.kt' },
+			{ startIndex: 38, type: 'keyword.vararg.kt' },
+			{ startIndex: 44, type: '' },
+			{ startIndex: 45, type: 'identifier.kt' },
+			{ startIndex: 49, type: 'delimiter.kt' },
+			{ startIndex: 50, type: '' },
+			{ startIndex: 51, type: 'type.identifier.kt' },
+			{ startIndex: 57, type: 'delimiter.parenthesis.kt' },
+			{ startIndex: 58, type: '' },
+			{ startIndex: 59, type: 'delimiter.curly.kt' },
+			{ startIndex: 61, type: '' },
+			{ startIndex: 62, type: 'delimiter.curly.kt' },
+			{ startIndex: 63, type: '' },
+			{ startIndex: 64, type: 'delimiter.curly.kt' }
+		]
+	}],
+
+	// Numbers
+	[{
+		line: '0',
+		tokens: [
+			{ startIndex: 0, type: 'number.kt' }
+		]
+	}],
+
+	[{
+		line: '0.10',
+		tokens: [
+			{ startIndex: 0, type: 'number.float.kt' }
+		]
+	}],
+
+	[{
+		line: '0x',
+		tokens: [
+			{ startIndex: 0, type: 'number.kt' },
+			{ startIndex: 1, type: 'identifier.kt' }
+		]
+	}],
+
+	[{
+		line: '0x123',
+		tokens: [
+			{ startIndex: 0, type: 'number.hex.kt' }
+		]
+	}],
+
+	[{
+		line: '0x5_2',
+		tokens: [
+			{ startIndex: 0, type: 'number.hex.kt' }
+		]
+	}],
+
+	[{
+		line: '023L',
+		tokens: [
+			{ startIndex: 0, type: 'number.octal.kt' }
+		]
+	}],
+
+	[{
+		line: '0123l',
+		tokens: [
+			{ startIndex: 0, type: 'number.octal.kt' }
+		]
+	}],
+
+	[{
+		line: '05_2',
+		tokens: [
+			{ startIndex: 0, type: 'number.octal.kt' }
+		]
+	}],
+
+	[{
+		line: '0b1010_0101',
+		tokens: [
+			{ startIndex: 0, type: 'number.binary.kt' }
+		]
+	}],
+
+	[{
+		line: '0B001',
+		tokens: [
+			{ startIndex: 0, type: 'number.binary.kt' }
+		]
+	}],
+
+	[{
+		line: '10e3',
+		tokens: [
+			{ startIndex: 0, type: 'number.float.kt' }
+		]
+	}],
+
+	[{
+		line: '10f',
+		tokens: [
+			{ startIndex: 0, type: 'number.float.kt' }
+		]
+	}],
+
+	[{
+		line: '23.5',
+		tokens: [
+			{ startIndex: 0, type: 'number.float.kt' }
+		]
+	}],
+
+	[{
+		line: '23.5e3',
+		tokens: [
+			{ startIndex: 0, type: 'number.float.kt' }
+		]
+	}],
+
+	[{
+		line: '23.5e-3',
+		tokens: [
+			{ startIndex: 0, type: 'number.float.kt' }
+		]
+	}],
+
+	[{
+		line: '23.5E3',
+		tokens: [
+			{ startIndex: 0, type: 'number.float.kt' }
+		]
+	}],
+
+	[{
+		line: '23.5E-3',
+		tokens: [
+			{ startIndex: 0, type: 'number.float.kt' }
+		]
+	}],
+
+	[{
+		line: '23.5F',
+		tokens: [
+			{ startIndex: 0, type: 'number.float.kt' }
+		]
+	}],
+
+	[{
+		line: '23.5f',
+		tokens: [
+			{ startIndex: 0, type: 'number.float.kt' }
+		]
+	}],
+
+	[{
+		line: '23.5D',
+		tokens: [
+			{ startIndex: 0, type: 'number.float.kt' }
+		]
+	}],
+
+	[{
+		line: '23.5d',
+		tokens: [
+			{ startIndex: 0, type: 'number.float.kt' }
+		]
+	}],
+
+	[{
+		line: '1.72E3D',
+		tokens: [
+			{ startIndex: 0, type: 'number.float.kt' }
+		]
+	}],
+
+	[{
+		line: '1.72E3d',
+		tokens: [
+			{ startIndex: 0, type: 'number.float.kt' }
+		]
+	}],
+
+	[{
+		line: '1.72E-3d',
+		tokens: [
+			{ startIndex: 0, type: 'number.float.kt' }
+		]
+	}],
+
+	[{
+		line: '1.72e3D',
+		tokens: [
+			{ startIndex: 0, type: 'number.float.kt' }
+		]
+	}],
+
+	[{
+		line: '1.72e3d',
+		tokens: [
+			{ startIndex: 0, type: 'number.float.kt' }
+		]
+	}],
+
+	[{
+		line: '1.72e-3d',
+		tokens: [
+			{ startIndex: 0, type: 'number.float.kt' }
+		]
+	}],
+
+	[{
+		line: '23L',
+		tokens: [
+			{ startIndex: 0, type: 'number.kt' }
+		]
+	}],
+
+	[{
+		line: '23l',
+		tokens: [
+			{ startIndex: 0, type: 'number.kt' }
+		]
+	}],
+
+	[{
+		line: '0_52',
+		tokens: [
+			{ startIndex: 0, type: 'number.kt' }
+		]
+	}],
+
+	[{
+		line: '5_2',
+		tokens: [
+			{ startIndex: 0, type: 'number.kt' }
+		]
+	}],
+
+	[{
+		line: '5_______2',
+		tokens: [
+			{ startIndex: 0, type: 'number.kt' }
+		]
+	}],
+
+	[{
+		line: '3_.1415F',
+		tokens: [
+			{ startIndex: 0, type: 'number.kt' },
+			{ startIndex: 1, type: 'identifier.kt' },
+			{ startIndex: 2, type: 'delimiter.kt' },
+			{ startIndex: 3, type: 'number.float.kt' }
+		]
+	}],
+
+	[{
+		line: '3._1415F',
+		tokens: [
+			{ startIndex: 0, type: 'number.kt' },
+			{ startIndex: 1, type: 'delimiter.kt' },
+			{ startIndex: 2, type: 'identifier.kt' }
+		]
+	}],
+
+	[{
+		line: '999_99_9999_L',
+		tokens: [
+			{ startIndex: 0, type: 'number.kt' },
+			{ startIndex: 11, type: 'identifier.kt' }
+		]
+	}],
+
+	[{
+		line: '52_',
+		tokens: [
+			{ startIndex: 0, type: 'number.kt' },
+			{ startIndex: 2, type: 'identifier.kt' }
+		]
+	}],
+
+	[{
+		line: '0_x52',
+		tokens: [
+			{ startIndex: 0, type: 'number.kt' },
+			{ startIndex: 1, type: 'identifier.kt' }
+		]
+	}],
+
+	[{
+		line: '0x_52',
+		tokens: [
+			{ startIndex: 0, type: 'number.kt' },
+			{ startIndex: 1, type: 'identifier.kt' }
+		]
+	}],
+
+	[{
+		line: '0x52_',
+		tokens: [
+			{ startIndex: 0, type: 'number.hex.kt' },
+			{ startIndex: 4, type: 'identifier.kt' }
+		]
+	}],
+
+	[{
+		line: '052_',
+		tokens: [
+			{ startIndex: 0, type: 'number.octal.kt' },
+			{ startIndex: 3, type: 'identifier.kt' }
+		]
+	}],
+
+	[{
+		line: '0+0',
+		tokens: [
+			{ startIndex: 0, type: 'number.kt' },
+			{ startIndex: 1, type: 'delimiter.kt' },
+			{ startIndex: 2, type: 'number.kt' }
+		]
+	}],
+
+	[{
+		line: '100+10',
+		tokens: [
+			{ startIndex: 0, type: 'number.kt' },
+			{ startIndex: 3, type: 'delimiter.kt' },
+			{ startIndex: 4, type: 'number.kt' }
+		]
+	}],
+
+	[{
+		line: '0 + 0',
+		tokens: [
+			{ startIndex: 0, type: 'number.kt' },
+			{ startIndex: 1, type: '' },
+			{ startIndex: 2, type: 'delimiter.kt' },
+			{ startIndex: 3, type: '' },
+			{ startIndex: 4, type: 'number.kt' }
+		]
+	}],
+
+	// single line Strings
+	[{
+		line: 'var s = "I\'m a Kotlin String"',
+		tokens: [
+			{ startIndex: 0, type: 'keyword.var.kt' },
+			{ startIndex: 3, type: '' },
+			{ startIndex: 4, type: 'identifier.kt' },
+			{ startIndex: 5, type: '' },
+			{ startIndex: 6, type: 'delimiter.kt' },
+			{ startIndex: 7, type: '' },
+			{ startIndex: 8, type: 'string.kt' },
+		]
+	}],
+
+	[{
+		line: 'var s = "concatenated" + " String"',
+		tokens: [
+			{ startIndex: 0, type: 'keyword.var.kt' },
+			{ startIndex: 3, type: '' },
+			{ startIndex: 4, type: 'identifier.kt' },
+			{ startIndex: 5, type: '' },
+			{ startIndex: 6, type: 'delimiter.kt' },
+			{ startIndex: 7, type: '' },
+			{ startIndex: 8, type: 'string.kt' },
+			{ startIndex: 22, type: '' },
+			{ startIndex: 23, type: 'delimiter.kt' },
+			{ startIndex: 24, type: '' },
+			{ startIndex: 25, type: 'string.kt' },
+		]
+	}],
+
+	[{
+		line: '"quote in a string"',
+		tokens: [
+			{ startIndex: 0, type: 'string.kt' }
+		]
+	}],
+
+	[{
+		line: '"escaping \\"quotes\\" is cool"',
+		tokens: [
+			{ startIndex: 0, type: 'string.kt' },
+			{ startIndex: 10, type: 'string.escape.kt' },
+			{ startIndex: 12, type: 'string.kt' },
+			{ startIndex: 18, type: 'string.escape.kt' },
+			{ startIndex: 20, type: 'string.kt' }
+		]
+	}],
+
+	[{
+		line: '"\\"',
+		tokens: [
+			{ startIndex: 0, type: 'string.invalid.kt' }
+		]
+	}],
+
+	// Annotations
+	[{
+		line: '@',
+		tokens: [
+			{ startIndex: 0, type: '' }
+		]
+	}],
+
+	[{
+		line: '@Inject',
+		tokens: [
+			{ startIndex: 0, type: 'annotation.kt' }
+		]
+	}],
+
+	[{
+		line: '@SuppressWarnings("aString")',
+		tokens: [
+			{ startIndex: 0, type: 'annotation.kt' },
+			{ startIndex: 17, type: 'delimiter.parenthesis.kt' },
+			{ startIndex: 18, type: 'string.kt' },
+			{ startIndex: 27, type: 'delimiter.parenthesis.kt' }
+		]
+	}],
+
+	[{
+		line: '@ AnnotationWithKeywordAfter private',
+		tokens: [
+			{ startIndex: 0, type: 'annotation.kt' },
+			{ startIndex: 28, type: '' },
+			{ startIndex: 29, type: 'keyword.private.kt' }
+		]
+	}]
+]);
+

+ 158 - 0
src/kotlin/kotlin.ts

@@ -0,0 +1,158 @@
+/*---------------------------------------------------------------------------------------------
+ *  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 = {
+	// the default separators except `@$`
+	wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g,
+	comments: {
+		lineComment: '//',
+		blockComment: ['/*', '*/'],
+	},
+	brackets: [
+		['{', '}'],
+		['[', ']'],
+		['(', ')'],
+	],
+	autoClosingPairs: [
+		{ open: '{', close: '}' },
+		{ open: '[', close: ']' },
+		{ open: '(', close: ')' },
+		{ open: '"', close: '"' },
+		{ open: '\'', close: '\'' },
+	],
+	surroundingPairs: [
+		{ open: '{', close: '}' },
+		{ open: '[', close: ']' },
+		{ open: '(', close: ')' },
+		{ open: '"', close: '"' },
+		{ open: '\'', close: '\'' },
+		{ open: '<', close: '>' },
+	],
+	folding: {
+		markers: {
+			start: new RegExp("^\\s*//\\s*(?:(?:#?region\\b)|(?:<editor-fold\\b))"),
+			end: new RegExp("^\\s*//\\s*(?:(?:#?endregion\\b)|(?:</editor-fold>))")
+		}
+	}
+};
+
+export const language = <ILanguage>{
+	defaultToken: '',
+	tokenPostfix: '.kt',
+
+	keywords: [
+		'as', 'as?', 'break', 'class', 'continue', 'do', 'else', 'false', 'for', 'fun', 'if',
+		'in', '!in', 'interface', 'is', '!is', 'null', 'object', 'package', 'return', 'super',
+		'this', 'throw', 'true', 'try', 'typealias', 'val', 'var', 'when', 'while', 'by',
+		'catch', 'constructor', 'delegate', 'dynamic', 'field', 'file', 'finally', 'get',
+		'import', 'init', 'param', 'property', 'receiver', 'set', 'setparam', 'where', 'actual',
+		'abstract','annotation', 'companion', 'const', 'crossinline', 'data', 'enum', 'expect',
+		'external', 'final', 'infix', 'inline', 'inner', 'internal', 'lateinit', 'noinline',
+		'open', 'operator', 'out', 'override', 'private', 'protected', 'public', 'reified',
+		'sealed', 'suspend', 'tailrec', 'vararg', 'field', 'it'
+	],
+
+	operators: [
+		'+', '-', '*', '/', '%', '=', '+=', '-=', '*=', '/=',
+		'%=', '++', '--', '&&', '||', '!', '==', '!=', '===',
+		'!==', '>', '<', '<=', '>=', '[', ']', '!!', '?.', '?:',
+		'::', '..', ':', '?', '->', '@', ';', '$', '_'
+	],
+
+	// we include these common regular expressions
+	symbols: /[=><!~?:&|+\-*\/\^%]+/,
+	escapes: /\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,
+	digits: /\d+(_+\d+)*/,
+	octaldigits: /[0-7]+(_+[0-7]+)*/,
+	binarydigits: /[0-1]+(_+[0-1]+)*/,
+	hexdigits: /[[0-9a-fA-F]+(_+[0-9a-fA-F]+)*/,
+
+	// The main tokenizer for our languages
+	tokenizer: {
+
+		root: [
+			// class name highlighting
+			[/[A-Z][\w\$]*/, 'type.identifier' ],
+
+			// identifiers and keywords
+			[/[a-zA-Z_$][\w$]*/, {
+				cases: {
+					'@keywords': { token: 'keyword.$0' },
+					'@default': 'identifier'
+				}
+			}],
+
+			// whitespace
+			{ include: '@whitespace' },
+
+			// delimiters and operators
+			[/[{}()\[\]]/, '@brackets'],
+			[/[<>](?!@symbols)/, '@brackets'],
+			[/@symbols/, {
+				cases: {
+					'@operators': 'delimiter',
+					'@default': ''
+				}
+			}],
+
+			// @ annotations.
+			[/@\s*[a-zA-Z_\$][\w\$]*/, 'annotation'],
+
+			// numbers
+			[/(@digits)[eE]([\-+]?(@digits))?[fFdD]?/, 'number.float'],
+			[/(@digits)\.(@digits)([eE][\-+]?(@digits))?[fFdD]?/, 'number.float'],
+			[/0[xX](@hexdigits)[Ll]?/, 'number.hex'],
+			[/0(@octaldigits)[Ll]?/, 'number.octal'],
+			[/0[bB](@binarydigits)[Ll]?/, 'number.binary'],
+			[/(@digits)[fFdD]/, 'number.float'],
+			[/(@digits)[lL]?/, 'number'],
+
+			// delimiter: after number because of .\d floats
+			[/[;,.]/, 'delimiter'],
+
+			// strings
+			[/"([^"\\]|\\.)*$/, 'string.invalid'],  // non-teminated string
+			[/"/, 'string', '@string'],
+
+			// characters
+			[/'[^\\']'/, 'string'],
+			[/(')(@escapes)(')/, ['string', 'string.escape', 'string']],
+			[/'/, 'string.invalid']
+		],
+
+		whitespace: [
+			[/[ \t\r\n]+/, ''],
+			[/\/\*\*(?!\/)/, 'comment.doc', '@javadoc'],
+			[/\/\*/, 'comment', '@comment'],
+			[/\/\/.*$/, 'comment'],
+		],
+
+		comment: [
+			[/[^\/*]+/, 'comment'],
+			[/\*\//, 'comment', '@pop'],
+			[/[\/*]/, 'comment']
+		],
+		//Identical copy of comment above, except for the addition of .doc
+		javadoc: [
+			[/[^\/*]+/, 'comment.doc'],
+			// [/\/\*/, 'comment.doc', '@push' ],    // nested comment not allowed :-(
+			[/\/\*/, 'comment.doc.invalid'],
+			[/\*\//, 'comment.doc', '@pop'],
+			[/[\/*]/, 'comment.doc']
+		],
+
+		string: [
+			[/[^\\"]+/, 'string'],
+			[/@escapes/, 'string.escape'],
+			[/\\./, 'string.escape.invalid'],
+			[/"/, 'string', '@pop']
+		],
+	},
+};

+ 1 - 4
src/less/less.contribution.ts

@@ -6,13 +6,10 @@
 
 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: 'less',
 	extensions: ['.less'],
 	aliases: ['Less', 'less'],
 	mimetypes: ['text/x-less', 'text/less'],
-	loader: () => _monaco.Promise.wrap(import('./less'))
+	loader: () => import('./less')
 });

+ 1 - 4
src/lua/lua.contribution.ts

@@ -6,12 +6,9 @@
 
 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: 'lua',
 	extensions: ['.lua'],
 	aliases: ['Lua', 'lua'],
-	loader: () => _monaco.Promise.wrap(import('./lua'))
+	loader: () => import('./lua')
 });

+ 1 - 4
src/markdown/markdown.contribution.ts

@@ -6,12 +6,9 @@
 
 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: 'markdown',
 	extensions: ['.md', '.markdown', '.mdown', '.mkdn', '.mkd', '.mdwn', '.mdtxt', '.mdtext'],
 	aliases: ['Markdown', 'markdown'],
-	loader: () => _monaco.Promise.wrap(import('./markdown'))
+	loader: () => import('./markdown')
 });

+ 2 - 0
src/monaco.contribution.ts

@@ -18,6 +18,7 @@ import './html/html.contribution';
 import './ini/ini.contribution';
 import './java/java.contribution';
 import './javascript/javascript.contribution';
+import './kotlin/kotlin.contribution';
 import './less/less.contribution';
 import './lua/lua.contribution';
 import './markdown/markdown.contribution';
@@ -54,3 +55,4 @@ import './shell/shell.contribution';
 import './perl/perl.contribution';
 import './azcli/azcli.contribution';
 import './apex/apex.contribution';
+import './graphql/graphql.contribution';

+ 1 - 4
src/msdax/msdax.contribution.ts

@@ -6,12 +6,9 @@
 
 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: 'msdax',
 	extensions: ['.dax', '.msdax'],
 	aliases: ['DAX', 'MSDAX'],
-	loader: () => _monaco.Promise.wrap(import('./msdax'))
+	loader: () => import('./msdax')
 });

+ 1 - 4
src/mysql/mysql.contribution.ts

@@ -6,12 +6,9 @@
 
 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: 'mysql',
 	extensions: [],
 	aliases: ['MySQL', 'mysql'],
-	loader: () => _monaco.Promise.wrap(import('./mysql'))
+	loader: () => import('./mysql')
 });

+ 1 - 4
src/objective-c/objective-c.contribution.ts

@@ -6,12 +6,9 @@
 
 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: 'objective-c',
 	extensions: ['.m'],
 	aliases: ['Objective-C'],
-	loader: () => _monaco.Promise.wrap(import('./objective-c'))
+	loader: () => import('./objective-c')
 });

+ 1 - 4
src/perl/perl.contribution.ts

@@ -6,12 +6,9 @@
 
 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: 'perl',
 	extensions: ['.pl'],
 	aliases: ['Perl', 'pl'],
-	loader: () => _monaco.Promise.wrap(import('./perl')),
+	loader: () => import('./perl'),
 });

+ 1 - 4
src/pgsql/pgsql.contribution.ts

@@ -6,12 +6,9 @@
 
 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: 'pgsql',
 	extensions: [],
 	aliases: ['PostgreSQL', 'postgres', 'pg', 'postgre'],
-	loader: () => _monaco.Promise.wrap(import('./pgsql'))
+	loader: () => import('./pgsql')
 });

+ 1 - 4
src/php/php.contribution.ts

@@ -6,13 +6,10 @@
 
 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: 'php',
 	extensions: ['.php', '.php4', '.php5', '.phtml', '.ctp'],
 	aliases: ['PHP', 'php'],
 	mimetypes: ['application/x-php'],
-	loader: () => _monaco.Promise.wrap(import('./php'))
+	loader: () => import('./php')
 });

+ 1 - 4
src/postiats/postiats.contribution.ts

@@ -6,12 +6,9 @@
 
 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: 'postiats',
 	extensions: ['.dats', '.sats', '.hats'],
 	aliases: ['ATS', 'ATS/Postiats'],
-	loader: () => _monaco.Promise.wrap(import('./postiats'))
+	loader: () => import('./postiats')
 });

+ 1 - 4
src/powerquery/powerquery.contribution.ts

@@ -6,12 +6,9 @@
 
 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: 'powerquery',
 	extensions: ['.pq', '.pqm'],
 	aliases: ['PQ', 'M', 'Power Query', 'Power Query M'],
-	loader: () => _monaco.Promise.wrap(import('./powerquery'))
+	loader: () => import('./powerquery')
 });

+ 1 - 4
src/powershell/powershell.contribution.ts

@@ -6,12 +6,9 @@
 
 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: 'powershell',
 	extensions: ['.ps1', '.psm1', '.psd1'],
 	aliases: ['PowerShell', 'powershell', 'ps', 'ps1'],
-	loader: () => _monaco.Promise.wrap(import('./powershell'))
+	loader: () => import('./powershell')
 });

+ 1 - 4
src/pug/pug.contribution.ts

@@ -6,12 +6,9 @@
 
 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: 'pug',
 	extensions: ['.jade', '.pug'],
 	aliases: ['Pug', 'Jade', 'jade'],
-	loader: () => _monaco.Promise.wrap(import('./pug'))
+	loader: () => import('./pug')
 });

+ 1 - 4
src/python/python.contribution.ts

@@ -6,13 +6,10 @@
 
 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: 'python',
 	extensions: ['.py', '.rpy', '.pyw', '.cpy', '.gyp', '.gypi'],
 	aliases: ['Python', 'py'],
 	firstLine: '^#!/.*\\bpython[0-9.-]*\\b',
-	loader: () => _monaco.Promise.wrap(import('./python'))
+	loader: () => import('./python')
 });

+ 1 - 4
src/r/r.contribution.ts

@@ -6,12 +6,9 @@
 
 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: 'r',
 	extensions: ['.r', '.rhistory', '.rprofile', '.rt'],
 	aliases: ['R', 'r'],
-	loader: () => _monaco.Promise.wrap(import('./r'))
+	loader: () => import('./r')
 });

+ 1 - 4
src/razor/razor.contribution.ts

@@ -6,13 +6,10 @@
 
 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: 'razor',
 	extensions: ['.cshtml'],
 	aliases: ['Razor', 'razor'],
 	mimetypes: ['text/x-cshtml'],
-	loader: () => _monaco.Promise.wrap(import('./razor'))
+	loader: () => import('./razor')
 });

+ 1 - 4
src/redis/redis.contribution.ts

@@ -6,12 +6,9 @@
 
 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: 'redis',
 	extensions: ['.redis'],
 	aliases: ['redis'],
-	loader: () => _monaco.Promise.wrap(import('./redis'))
+	loader: () => import('./redis')
 });

+ 1 - 4
src/redshift/redshift.contribution.ts

@@ -6,12 +6,9 @@
 
 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: 'redshift',
 	extensions: [],
 	aliases: ['Redshift', 'redshift'],
-	loader: () => _monaco.Promise.wrap(import('./redshift'))
+	loader: () => import('./redshift')
 });

+ 1 - 4
src/ruby/ruby.contribution.ts

@@ -6,13 +6,10 @@
 
 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: 'ruby',
 	extensions: ['.rb', '.rbx', '.rjs', '.gemspec', '.pp'],
 	filenames: ['rakefile'],
 	aliases: ['Ruby', 'rb'],
-	loader: () => _monaco.Promise.wrap(import('./ruby'))
+	loader: () => import('./ruby')
 });

+ 5 - 1
src/ruby/ruby.ts

@@ -31,7 +31,11 @@ export const conf: IRichLanguageConfiguration = {
 		{ open: '(', close: ')' },
 		{ open: '"', close: '"' },
 		{ open: '\'', close: '\'' },
-	]
+	],
+	indentationRules: {
+		increaseIndentPattern: new RegExp('^\\s*((begin|class|(private|protected)\\s+def|def|else|elsif|ensure|for|if|module|rescue|unless|until|when|while|case)|([^#]*\\sdo\\b)|([^#]*=\\s*(case|if|unless)))\\b([^#\\{;]|("|\'|\/).*\\4)*(#.*)?$'),
+		decreaseIndentPattern: new RegExp('^\\s*([}\\]]([,)]?\\s*(#|$)|\\.[a-zA-Z_]\\w*\\b)|(end|rescue|ensure|else|elsif|when)\\b)'),
+	}
 };
 
 /*

+ 1 - 4
src/rust/rust.contribution.ts

@@ -6,12 +6,9 @@
 
 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'))
+	loader: () => import('./rust')
 });

+ 1 - 4
src/sb/sb.contribution.ts

@@ -6,12 +6,9 @@
 
 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: 'sb',
 	extensions: ['.sb'],
 	aliases: ['Small Basic', 'sb'],
-	loader: () => _monaco.Promise.wrap(import('./sb'))
+	loader: () => import('./sb')
 });

+ 1 - 5
src/scheme/scheme.contribution.ts

@@ -6,13 +6,9 @@
 
 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: 'scheme',
     extensions: ['.scm', '.ss', '.sch', '.rkt'],
     aliases: ['scheme', 'Scheme'],
-    loader: () => _monaco.Promise.wrap(import('./scheme')),
+    loader: () => import('./scheme'),
 });

+ 1 - 4
src/scss/scss.contribution.ts

@@ -6,13 +6,10 @@
 
 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: 'scss',
 	extensions: ['.scss'],
 	aliases: ['Sass', 'sass', 'scss'],
 	mimetypes: ['text/x-scss', 'text/scss'],
-	loader: () => _monaco.Promise.wrap(import('./scss'))
+	loader: () => import('./scss')
 });

+ 1 - 5
src/shell/shell.contribution.ts

@@ -6,13 +6,9 @@
 
 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: 'shell',
 	extensions: ['.sh', '.bash'],
 	aliases: ['Shell', 'sh'],
-	loader: () => _monaco.Promise.wrap(import('./shell')),
+	loader: () => import('./shell'),
 });

+ 1 - 4
src/solidity/solidity.contribution.ts

@@ -6,12 +6,9 @@
 
 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: 'sol',
 	extensions: ['.sol'],
 	aliases: ['sol', 'solidity', 'Solidity'],
-	loader: () => _monaco.Promise.wrap(import('./solidity'))
+	loader: () => import('./solidity')
 });

+ 1 - 4
src/sql/sql.contribution.ts

@@ -6,12 +6,9 @@
 
 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: 'sql',
 	extensions: ['.sql'],
 	aliases: ['SQL'],
-	loader: () => _monaco.Promise.wrap(import('./sql'))
+	loader: () => import('./sql')
 });

+ 1 - 4
src/st/st.contribution.ts

@@ -6,12 +6,9 @@
 
 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: 'st',
 	extensions: ['.st', '.iecst', '.iecplc', '.lc3lib'],
 	aliases: ['StructuredText', 'scl', 'stl'],
-	loader: () => _monaco.Promise.wrap(import('./st'))
+	loader: () => import('./st')
 });

+ 1 - 4
src/swift/swift.contribution.ts

@@ -6,13 +6,10 @@
 
 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: 'swift',
 	aliases: ['Swift', 'swift'],
 	extensions: ['.swift'],
 	mimetypes: ['text/swift'],
-	loader: () => _monaco.Promise.wrap(import('./swift'))
+	loader: () => import('./swift')
 });

+ 1 - 3
src/tcl/tcl.contribution.ts

@@ -6,11 +6,9 @@
 
 import {registerLanguage} from '../_.contribution';
 
-const _monaco: typeof monaco = (typeof monaco === 'undefined' ? (<any>self).monaco : monaco);
-
 registerLanguage({
 	id: 'tcl',
 	extensions: ['.tcl'],
 	aliases: ['tcl', 'Tcl', 'tcltk', 'TclTk', 'tcl/tk', 'Tcl/Tk'],
-	loader: () => _monaco.Promise.wrap(import('./tcl'))
+	loader: () => import('./tcl')
 });

+ 1 - 1
src/test/testRunner.ts

@@ -30,7 +30,7 @@ export function testTokenization(_language:string|string[], tests:ITestItem[][])
 	let mainLanguage = languages[0];
 	suite(mainLanguage + ' tokenization', () => {
 		test('', (done) => {
-			_monaco.Promise.join(languages.map(l => loadLanguage(l))).then(() => {
+			Promise.all(languages.map(l => loadLanguage(l))).then(() => {
 				// clean stack
 				setTimeout(() => {
 					runTests(mainLanguage, tests);

+ 1 - 4
src/typescript/typescript.contribution.ts

@@ -6,13 +6,10 @@
 
 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: 'typescript',
 	extensions: ['.ts', '.tsx'],
 	aliases: ['TypeScript', 'ts', 'typescript'],
 	mimetypes: ['text/typescript'],
-	loader: () => _monaco.Promise.wrap(<Promise<any>>import('./typescript'))
+	loader: () => <Promise<any>>import('./typescript')
 });

+ 1 - 4
src/vb/vb.contribution.ts

@@ -6,12 +6,9 @@
 
 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: 'vb',
 	extensions: ['.vb'],
 	aliases: ['Visual Basic', 'vb'],
-	loader: () => _monaco.Promise.wrap(import('./vb'))
+	loader: () => import('./vb')
 });

+ 1 - 4
src/xml/xml.contribution.ts

@@ -6,14 +6,11 @@
 
 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: 'xml',
 	extensions: ['.xml', '.dtd', '.ascx', '.csproj', '.config', '.wxi', '.wxl', '.wxs', '.xaml', '.svg', '.svgz'],
 	firstLine: '(\\<\\?xml.*)|(\\<svg)|(\\<\\!doctype\\s+svg)',
 	aliases: ['XML', 'xml'],
 	mimetypes: ['text/xml', 'application/xml', 'application/xaml+xml', 'application/xml-dtd'],
-	loader: () => _monaco.Promise.wrap(import('./xml'))
+	loader: () => import('./xml')
 });

+ 1 - 4
src/yaml/yaml.contribution.ts

@@ -6,13 +6,10 @@
 
 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: 'yaml',
 	extensions: ['.yaml', '.yml'],
 	aliases: ['YAML', 'yaml', 'YML', 'yml'],
 	mimetypes: ['application/x-yaml'],
-	loader: () => _monaco.Promise.wrap(import('./yaml'))
+	loader: () => import('./yaml')
 });

+ 2 - 0
test/setup.js

@@ -37,10 +37,12 @@ define(['require'], function () {
 			'release/dev/dockerfile/dockerfile.test',
 			'release/dev/fsharp/fsharp.test',
 			'release/dev/go/go.test',
+			'release/dev/graphql/graphql.test',
 			'release/dev/handlebars/handlebars.test',
 			'release/dev/html/html.test',
 			'release/dev/java/java.test',
 			'release/dev/javascript/javascript.test',
+			'release/dev/kotlin/kotlin.test',
 			'release/dev/less/less.test',
 			'release/dev/lua/lua.test',
 			'release/dev/markdown/markdown.test',