From faf8fd35c177535ed733f122177bf3706d7f47db Mon Sep 17 00:00:00 2001 From: Andrew Watson Date: Fri, 7 Dec 2018 16:19:01 -0800 Subject: [PATCH 1/8] Add kotlin-related files, start introducing language constructs --- src/kotlin/kotlin.contribution.ts | 18 +++ src/kotlin/kotlin.ts | 209 ++++++++++++++++++++++++++++++ 2 files changed, 227 insertions(+) create mode 100644 src/kotlin/kotlin.contribution.ts create mode 100644 src/kotlin/kotlin.ts diff --git a/src/kotlin/kotlin.contribution.ts b/src/kotlin/kotlin.contribution.ts new file mode 100644 index 00000000..b56711f0 --- /dev/null +++ b/src/kotlin/kotlin.contribution.ts @@ -0,0 +1,18 @@ +/*--------------------------------------------------------------------------------------------- + * 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' ? (self).monaco : monaco); + +registerLanguage({ + id: 'kotlin', + extensions: ['.kt'], + aliases: ['Kotlin', 'kotlin'], + mimetypes: ['text/x-kotlin-source', 'text/x-kotlin'], + loader: () => _monaco.Promise.wrap(import('./kotlin')) +}); diff --git a/src/kotlin/kotlin.ts b/src/kotlin/kotlin.ts new file mode 100644 index 00000000..82e166b6 --- /dev/null +++ b/src/kotlin/kotlin.ts @@ -0,0 +1,209 @@ +/*--------------------------------------------------------------------------------------------- + * 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)|(?:))") + } + } +}; + +export const language = { + defaultToken: '', + tokenPostfix: '.java', + + keywords: [ + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + + ], + + operators: [ + '=', '>', '<', '!', '~', '?', ':', + '==', '<=', '>=', '!=', '&&', '||', '++', '--', + '+', '-', '*', '/', '&', '|', '^', '%', '<<', + '>>', '>>>', '+=', '-=', '*=', '/=', '&=', '|=', + '^=', '%=', '<<=', '>>=', '>>>=' + ], + + // we include these common regular expressions + symbols: /[=>](?!@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', '@push' ], // nested comment not allowed :-( + // [/\/\*/, 'comment.invalid' ], // this breaks block comments in the shape of /* //*/ + [/\*\//, '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'] + ], + }, +}; From 0d3e237e27710bd828381cce6813be4f17a84947 Mon Sep 17 00:00:00 2001 From: Andrew Watson Date: Fri, 7 Dec 2018 16:35:14 -0800 Subject: [PATCH 2/8] Add keywords --- src/kotlin/kotlin.ts | 76 +++++++------------------------------------- 1 file changed, 12 insertions(+), 64 deletions(-) diff --git a/src/kotlin/kotlin.ts b/src/kotlin/kotlin.ts index 82e166b6..c21a2a95 100644 --- a/src/kotlin/kotlin.ts +++ b/src/kotlin/kotlin.ts @@ -10,7 +10,7 @@ import ILanguage = monaco.languages.IMonarchLanguage; export const conf: IRichLanguageConfiguration = { // the default separators except `@$` - wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g, + //wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g, comments: { lineComment: '//', blockComment: ['/*', '*/'], @@ -37,8 +37,8 @@ export const conf: IRichLanguageConfiguration = { ], folding: { markers: { - start: new RegExp("^\\s*//\\s*(?:(?:#?region\\b)|(?:))") + //start: new RegExp("^\\s*//\\s*(?:(?:#?region\\b)|(?:))") } } }; @@ -48,67 +48,15 @@ export const language = { tokenPostfix: '.java', 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: [ From c071453275d126841179fd7640e8fefac74776d7 Mon Sep 17 00:00:00 2001 From: Andrew Watson Date: Fri, 7 Dec 2018 16:45:09 -0800 Subject: [PATCH 3/8] Add operators --- src/kotlin/kotlin.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/kotlin/kotlin.ts b/src/kotlin/kotlin.ts index c21a2a95..bfe00319 100644 --- a/src/kotlin/kotlin.ts +++ b/src/kotlin/kotlin.ts @@ -60,11 +60,10 @@ export const language = { ], operators: [ - '=', '>', '<', '!', '~', '?', ':', - '==', '<=', '>=', '!=', '&&', '||', '++', '--', - '+', '-', '*', '/', '&', '|', '^', '%', '<<', - '>>', '>>>', '+=', '-=', '*=', '/=', '&=', '|=', - '^=', '%=', '<<=', '>>=', '>>>=' + '+', '-', '*', '/', '%', '=', '+=', '-=', '*=', '/=', + '%=', '++', '--', '&&', '||', '!', '==', '!=', '===', + '!==', '>', '<', '<=', '>=', '[', ']', '!!', '?.', '?:', + '::', '..', ':', '?', '->', '@', ';', '$', '_' ], // we include these common regular expressions @@ -133,8 +132,6 @@ export const language = { comment: [ [/[^\/*]+/, 'comment'], - // [/\/\*/, 'comment', '@push' ], // nested comment not allowed :-( - // [/\/\*/, 'comment.invalid' ], // this breaks block comments in the shape of /* //*/ [/\*\//, 'comment', '@pop'], [/[\/*]/, 'comment'] ], From 41797ecbbb30bd1c306490be4de4691ce15e4439 Mon Sep 17 00:00:00 2001 From: Andrew Watson Date: Fri, 7 Dec 2018 16:56:35 -0800 Subject: [PATCH 4/8] Update the language now, add monaco contrib --- src/kotlin/kotlin.ts | 8 ++++---- src/monaco.contribution.ts | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/kotlin/kotlin.ts b/src/kotlin/kotlin.ts index bfe00319..8d8210d4 100644 --- a/src/kotlin/kotlin.ts +++ b/src/kotlin/kotlin.ts @@ -10,10 +10,10 @@ import ILanguage = monaco.languages.IMonarchLanguage; export const conf: IRichLanguageConfiguration = { // the default separators except `@$` - //wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g, + wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g, comments: { lineComment: '//', - blockComment: ['/*', '*/'], + blockComment: ['/**', '*/'], }, brackets: [ ['{', '}'], @@ -37,8 +37,8 @@ export const conf: IRichLanguageConfiguration = { ], folding: { markers: { - //start: new RegExp("^\\s*//\\s*(?:(?:#?region\\b)|(?:))") + start: new RegExp("^\\s*//\\s*(?:(?:#?region\\b)|(?:))") } } }; diff --git a/src/monaco.contribution.ts b/src/monaco.contribution.ts index ae9aad59..9704c086 100644 --- a/src/monaco.contribution.ts +++ b/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'; From 140cba979d69eaf5add3c518a905652db479e1ca Mon Sep 17 00:00:00 2001 From: Andrew Watson Date: Fri, 7 Dec 2018 17:25:08 -0800 Subject: [PATCH 5/8] Lotsa upates getting tests to pass --- src/kotlin/kotlin.test.ts | 647 ++++++++++++++++++++++++++++++++++++++ src/kotlin/kotlin.ts | 4 +- test/setup.js | 1 + 3 files changed, 650 insertions(+), 2 deletions(-) create mode 100644 src/kotlin/kotlin.test.ts diff --git a/src/kotlin/kotlin.test.ts b/src/kotlin/kotlin.test.ts new file mode 100644 index 00000000..9e6a1743 --- /dev/null +++ b/src/kotlin/kotlin.test.ts @@ -0,0 +1,647 @@ +/*--------------------------------------------------------------------------------------------- + * 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', [ + // 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(args: String[]) {} } }', + tokens: [ + { startIndex: 0, type: 'keyword.package.kt' }, + { startIndex: 7, type: '' }, + { startIndex: 8, type: 'identifier.kt' }, + { startIndex: 12, type: 'delimiter.kt' }, + { startIndex: 13, type: '' }, + { startIndex: 14, type: 'keyword.class.kt' }, + { startIndex: 19, type: '' }, + { startIndex: 20, type: 'identifier.kt' }, + { startIndex: 27, type: '' }, + { startIndex: 28, type: 'delimiter.curly.kt' }, + { startIndex: 29, type: '' }, + { startIndex: 30, type: 'keyword.fun.kt' }, + { startIndex: 36, type: '' }, + { startIndex: 42, type: 'identifier.kt' }, + { startIndex: 46, type: 'delimiter.parenthesis.kt' }, + { startIndex: 47, type: 'identifier.kt' }, + { startIndex: 53, type: 'delimiter.square.kt' }, + { startIndex: 55, type: '' }, + { startIndex: 56, type: 'identifier.kt' }, + { startIndex: 60, type: 'delimiter.parenthesis.kt' }, + { startIndex: 61, type: '' }, + { startIndex: 62, type: 'delimiter.curly.kt' }, + { startIndex: 64, type: '' }, + { startIndex: 65, type: 'delimiter.curly.kt' }, + { startIndex: 66, type: '' }, + { startIndex: 67, 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: '23.5L', + tokens: [ + { startIndex: 0, type: 'number.float.kt' }, + { startIndex: 4, 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: 'identifier.kt' }, + { startIndex: 6, type: '' }, + { startIndex: 7, type: 'identifier.kt' }, + { startIndex: 8, type: '' }, + { startIndex: 9, type: 'delimiter.kt' }, + { startIndex: 10, type: '' }, + { startIndex: 11, type: 'string.kt' }, + { startIndex: 30, type: 'delimiter.kt' } + ] + }], + + [{ + line: 'String s = "concatenated" + " String" ;', + tokens: [ + { startIndex: 0, type: 'identifier.kt' }, + { startIndex: 6, type: '' }, + { startIndex: 7, type: 'identifier.kt' }, + { startIndex: 8, type: '' }, + { startIndex: 9, type: 'delimiter.kt' }, + { startIndex: 10, type: '' }, + { startIndex: 11, type: 'string.kt' }, + { startIndex: 25, type: '' }, + { startIndex: 26, type: 'delimiter.kt' }, + { startIndex: 27, type: '' }, + { startIndex: 28, type: 'string.kt' }, + { startIndex: 37, type: '' }, + { startIndex: 38, type: 'delimiter.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: '@Override', + tokens: [ + { startIndex: 0, type: 'annotation.kt' } + ] + }], + + [{ + line: '@SuppressWarnings(value = "aString")', + tokens: [ + { startIndex: 0, type: 'annotation.kt' }, + { startIndex: 17, type: 'delimiter.parenthesis.kt' }, + { startIndex: 18, type: 'identifier.kt' }, + { startIndex: 23, type: '' }, + { startIndex: 24, type: 'delimiter.kt' }, + { startIndex: 25, type: '' }, + { startIndex: 26, type: 'string.kt' }, + { startIndex: 35, type: 'delimiter.parenthesis.kt' } + ] + }], + + [{ + line: '@ AnnotationWithKeywordAfter private', + tokens: [ + { startIndex: 0, type: 'annotation.kt' }, + { startIndex: 28, type: '' }, + { startIndex: 29, type: 'keyword.private.kt' } + ] + }] +]); + diff --git a/src/kotlin/kotlin.ts b/src/kotlin/kotlin.ts index 8d8210d4..732ef3f8 100644 --- a/src/kotlin/kotlin.ts +++ b/src/kotlin/kotlin.ts @@ -13,7 +13,7 @@ export const conf: IRichLanguageConfiguration = { wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g, comments: { lineComment: '//', - blockComment: ['/**', '*/'], + blockComment: ['/*', '*/'], }, brackets: [ ['{', '}'], @@ -45,7 +45,7 @@ export const conf: IRichLanguageConfiguration = { export const language = { defaultToken: '', - tokenPostfix: '.java', + tokenPostfix: '.kt', keywords: [ 'as', 'as?', 'break', 'class', 'continue', 'do', 'else', 'false', 'for', 'fun', 'if', diff --git a/test/setup.js b/test/setup.js index fe8c8534..b7ce51ed 100644 --- a/test/setup.js +++ b/test/setup.js @@ -42,6 +42,7 @@ define(['require'], function () { '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', From a6f2e04d34cb4af7baf0571431cc0629c94bc1f7 Mon Sep 17 00:00:00 2001 From: Andrew Watson Date: Fri, 7 Dec 2018 17:54:35 -0800 Subject: [PATCH 6/8] Finish up getting tests working --- src/kotlin/kotlin.test.ts | 106 +++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/src/kotlin/kotlin.test.ts b/src/kotlin/kotlin.test.ts index 9e6a1743..58dda733 100644 --- a/src/kotlin/kotlin.test.ts +++ b/src/kotlin/kotlin.test.ts @@ -184,36 +184,43 @@ testTokenization('kotlin', [ ] }], +/** + +package test class Program { fun main(vararg args: String) {} } } + + */ + // Keywords [{ - line: 'package test; class Program { fun main(args: String[]) {} } }', + 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: 'delimiter.kt' }, - { startIndex: 13, type: '' }, - { startIndex: 14, type: 'keyword.class.kt' }, - { startIndex: 19, type: '' }, - { startIndex: 20, type: 'identifier.kt' }, - { startIndex: 27, type: '' }, - { startIndex: 28, type: 'delimiter.curly.kt' }, - { startIndex: 29, type: '' }, - { startIndex: 30, type: 'keyword.fun.kt' }, - { startIndex: 36, type: '' }, - { startIndex: 42, type: 'identifier.kt' }, - { startIndex: 46, type: 'delimiter.parenthesis.kt' }, - { startIndex: 47, type: 'identifier.kt' }, - { startIndex: 53, type: 'delimiter.square.kt' }, - { startIndex: 55, type: '' }, - { startIndex: 56, type: 'identifier.kt' }, - { startIndex: 60, type: 'delimiter.parenthesis.kt' }, + { startIndex: 12, type: '' }, + { startIndex: 13, type: 'keyword.class.kt' }, + { startIndex: 18, type: '' }, + { startIndex: 19, 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: '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: 64, type: '' }, - { startIndex: 65, type: 'delimiter.curly.kt' }, - { startIndex: 66, type: '' }, - { startIndex: 67, type: 'delimiter.curly.kt' } + { startIndex: 63, type: '' }, + { startIndex: 64, type: 'delimiter.curly.kt' } ] }], @@ -549,35 +556,32 @@ testTokenization('kotlin', [ // single line Strings [{ - line: 'var s = "I\'m a Kotlin String";', + line: 'var s = "I\'m a Kotlin String"', tokens: [ - { startIndex: 0, type: 'identifier.kt' }, - { startIndex: 6, type: '' }, - { startIndex: 7, type: 'identifier.kt' }, - { startIndex: 8, type: '' }, - { startIndex: 9, type: 'delimiter.kt' }, - { startIndex: 10, type: '' }, - { startIndex: 11, type: 'string.kt' }, - { startIndex: 30, type: 'delimiter.kt' } + { 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: 'String s = "concatenated" + " String" ;', + line: 'var s = "concatenated" + " String"', tokens: [ - { startIndex: 0, type: 'identifier.kt' }, - { startIndex: 6, type: '' }, - { startIndex: 7, type: 'identifier.kt' }, - { startIndex: 8, type: '' }, - { startIndex: 9, type: 'delimiter.kt' }, - { startIndex: 10, type: '' }, - { startIndex: 11, type: 'string.kt' }, - { startIndex: 25, type: '' }, - { startIndex: 26, type: 'delimiter.kt' }, - { startIndex: 27, type: '' }, - { startIndex: 28, type: 'string.kt' }, - { startIndex: 37, type: '' }, - { startIndex: 38, type: 'delimiter.kt' } + { 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' }, ] }], @@ -615,23 +619,19 @@ testTokenization('kotlin', [ }], [{ - line: '@Override', + line: '@Inject', tokens: [ { startIndex: 0, type: 'annotation.kt' } ] }], [{ - line: '@SuppressWarnings(value = "aString")', + line: '@SuppressWarnings("aString")', tokens: [ { startIndex: 0, type: 'annotation.kt' }, { startIndex: 17, type: 'delimiter.parenthesis.kt' }, - { startIndex: 18, type: 'identifier.kt' }, - { startIndex: 23, type: '' }, - { startIndex: 24, type: 'delimiter.kt' }, - { startIndex: 25, type: '' }, - { startIndex: 26, type: 'string.kt' }, - { startIndex: 35, type: 'delimiter.parenthesis.kt' } + { startIndex: 18, type: 'string.kt' }, + { startIndex: 27, type: 'delimiter.parenthesis.kt' } ] }], From 0eed4aa6528a4645372938d100dbfde3835ec64c Mon Sep 17 00:00:00 2001 From: Andrew Watson Date: Fri, 7 Dec 2018 17:55:55 -0800 Subject: [PATCH 7/8] Add language to bundle js --- scripts/bundle.js | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/bundle.js b/scripts/bundle.js index 614d5c83..a59785a6 100644 --- a/scripts/bundle.js +++ b/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'); From 2683160fab01e0ab5dd66d18ff74f923f05b5a19 Mon Sep 17 00:00:00 2001 From: Caleb Tseng Date: Mon, 10 Dec 2018 14:53:49 -0800 Subject: [PATCH 8/8] Adding class highlighting and unit tests --- src/kotlin/kotlin.test.ts | 56 ++++++++++++++++++++++++++++----------- src/kotlin/kotlin.ts | 4 +++ 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/src/kotlin/kotlin.test.ts b/src/kotlin/kotlin.test.ts index 58dda733..848fc768 100644 --- a/src/kotlin/kotlin.test.ts +++ b/src/kotlin/kotlin.test.ts @@ -8,6 +8,44 @@ import { testTokenization } from '../test/testRunner'; testTokenization('kotlin', [ + // inline reified function + [{ + line: 'inline fun 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: '//', @@ -184,12 +222,6 @@ testTokenization('kotlin', [ ] }], -/** - -package test class Program { fun main(vararg args: String) {} } } - - */ - // Keywords [{ line: 'package test class Program { fun main(vararg args: String) {} } }', @@ -200,7 +232,7 @@ package test class Program { fun main(vararg args: String) {} } } { startIndex: 12, type: '' }, { startIndex: 13, type: 'keyword.class.kt' }, { startIndex: 18, type: '' }, - { startIndex: 19, type: 'identifier.kt' }, + { startIndex: 19, type: 'type.identifier.kt' }, { startIndex: 26, type: '' }, { startIndex: 27, type: 'delimiter.curly.kt' }, { startIndex: 28, type: '' }, @@ -213,7 +245,7 @@ package test class Program { fun main(vararg args: String) {} } } { startIndex: 45, type: 'identifier.kt' }, { startIndex: 49, type: 'delimiter.kt' }, { startIndex: 50, type: '' }, - { startIndex: 51, type: 'identifier.kt' }, + { startIndex: 51, type: 'type.identifier.kt' }, { startIndex: 57, type: 'delimiter.parenthesis.kt' }, { startIndex: 58, type: '' }, { startIndex: 59, type: 'delimiter.curly.kt' }, @@ -517,14 +549,6 @@ package test class Program { fun main(vararg args: String) {} } } ] }], - [{ - line: '23.5L', - tokens: [ - { startIndex: 0, type: 'number.float.kt' }, - { startIndex: 4, type: 'identifier.kt' } - ] - }], - [{ line: '0+0', tokens: [ diff --git a/src/kotlin/kotlin.ts b/src/kotlin/kotlin.ts index 732ef3f8..6e57fc0b 100644 --- a/src/kotlin/kotlin.ts +++ b/src/kotlin/kotlin.ts @@ -76,7 +76,11 @@ export const language = { // The main tokenizer for our languages tokenizer: { + root: [ + // class name highlighting + [/[A-Z][\w\$]*/, 'type.identifier' ], + // identifiers and keywords [/[a-zA-Z_$][\w$]*/, { cases: {