diff --git a/src/lang-kotlin.js b/src/lang-kotlin.js new file mode 100644 index 00000000..7f4bc2c4 --- /dev/null +++ b/src/lang-kotlin.js @@ -0,0 +1,58 @@ +/** + * @license + * Copyright (C) 2017 Michał Bączkowski + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @fileoverview + * Registers a language handler for Kotlin. + * + * Limitations: + * - doesn't support string interpolation ("$var") + * - doesn't support labels if there is no space between the keyword (break@loop, loop@for) + * + * @author mibac138@gmail.com + */ + +PR['registerLangHandler']( + PR['createSimpleLexer']( + [ + [PR['PR_PLAIN'], /^[\t\n\r \xA0]+/, null, '\t\n\r \xA0'], + [PR['PR_PUNCTUATION'], /^[.!%&()*+,\-;<=>?\[\\\]^{|}:]+/, null, '.!%&()*+,-;<=>?[\\]^{|}:'] + ], + [ + // keywords + [PR['PR_KEYWORD'], + /^\b(package|public|protected|private|open|abstract|constructor|final|override|import|for|while|as|typealias|get|set|((data|enum|annotation|sealed) )?class|this|super|val|var|fun|is|in|throw|return|break|continue|(companion )?object|if|try|else|do|when|init|interface|typeof)\b/], + [PR['PR_LITERAL'], /^(?:true|false|null)\b/], + // number literals + [PR['PR_LITERAL'], /^(0[xX][0-9a-fA-F_]+L?|0[bB][0-1]+L?|[0-9_.]+([eE]-?[0-9]+)?[fFL]?)/], + [PR['PR_TYPE'], /^(\b[A-Z]+[a-z][a-zA-Z0-9_$@]*|`.*`)/, null], + //double slash comments + [PR['PR_COMMENT'], /^\/\/.*/], + //slash star comments and documentation + [PR['PR_COMMENT'], /^\/\*[\s\S]*?(?:\*\/|$)/], + // char + [PR['PR_STRING'], /'.'/], + // string + [PR['PR_STRING'], /^"([^"\\]|\\[\s\S])*"/], + // multiline string + [PR['PR_STRING'], /^"{3}[\s\S]*?[^\\]"{3}/], + // annotation (and label) + [PR['PR_LITERAL'], /^@([a-zA-Z0-9_$@]*|`.*`)/], + // label definition + [PR['PR_LITERAL'], /^[a-zA-Z0-9_]+@/] + ]), + ['kotlin']); diff --git a/tests/prettify_test_2.html b/tests/prettify_test_2.html index 3ad9d72f..c62e032b 100644 --- a/tests/prettify_test_2.html +++ b/tests/prettify_test_2.html @@ -26,6 +26,7 @@ 'lang-css.js', 'lang-dart.js', 'lang-ex.js', + 'lang-kotlin.js', 'lang-lisp.js', 'lang-llvm.js', 'lang-matlab.js', @@ -1140,5 +1141,65 @@

Elixir

end +

Kotlin

+
+package test;
+
+import kotlin.Int
+
+// Single line comment
+/*
+ * Multiline
+ * comment
+ */
+
+typealias SomeNumber = Int
+
+val number: Long = 1_000L
+var float: Float = 12.34f
+0xFF_FF
+3.14
+
+314e-2
+0.314e1
+
+protected override fun ifBoolean(condition: Boolean? = null) {}
+
+::ifBoolean
+
+constructor() : super()
+
+"\"true\""
+'a'
+
+"""
+aaaaaaaaaaa
+"""
+
+loop@ for()
+
+break @loop
+
+enum class `true`
+
+data class Person(val name: String)
+
+enum class Size {
+    BIG, MEDIUM, SMALL
+}
+
+class Ball(val color: String, val size: Size) {
+    companion object {}
+
+    fun isBig() = size == Size.BIG
+
+    val isMedium: Boolean
+        get() = size == Size.MEDIUM
+}
+
+fun Boolean?.isNull(): Boolean = this == null
+
+fun Boolean?.getOrThrow(): Boolean = this ?: throw Exception()
+
diff --git a/tests/prettify_test_2.js b/tests/prettify_test_2.js index 239ca887..03e29f5a 100644 --- a/tests/prettify_test_2.js +++ b/tests/prettify_test_2.js @@ -708,6 +708,66 @@ var goldens = { ' `END`KWDEND`END`PUN;`END`PLN\n' + '`END`KWDEND`END`PUN;`END' ), + kotlin: ( + '`KWDpackage`END`PLN test`END`PUN;`END`PLN\n' + + '\n' + + '`END`KWDimport`END`PLN kotlin`END`PUN.`END`TYPInt`END`PLN\n' + + '\n' + + '`END`COM// Single line comment`END`PLN\n' + + '`END`COM/*\n' + + ' * Multiline\n' + + ' * comment\n' + + ' */`END`PLN\n' + + '\n' + + '`END`KWDtypealias`END`PLN `END`TYPSomeNumber`END`PLN `END`PUN=`END`PLN `END`TYPInt`END`PLN\n' + + '\n' + + '`END`KWDval`END`PLN number`END`PUN:`END`PLN `END`TYPLong`END`PLN `END`PUN=`END`PLN `END`LIT1_000L`END`PLN\n' + + '`END`KWDvar`END`PLN float`END`PUN:`END`PLN `END`TYPFloat`END`PLN `END`PUN=`END`PLN `END`LIT12.34f`END`PLN\n' + + '`END`LIT0xFF_FF`END`PLN\n' + + '`END`LIT3.14`END`PLN\n' + + '\n' + + '`END`LIT314e-2`END`PLN\n' + + '`END`LIT0.314e1`END`PLN\n' + + '\n' + + '`END`KWDprotected`END`PLN `END`KWDoverride`END`PLN `END`KWDfun`END`PLN ifBoolean`END`PUN(`END`PLNcondition`END`PUN:`END`PLN `END`TYPBoolean`END`PUN?`END`PLN `END`PUN=`END`PLN `END`LITnull`END`PUN)`END' + + '`PLN `END`PUN{}`END`PLN\n' + + '\n' + + '`END`PUN::`END`PLNifBoolean\n' + + '\n' + + '`END`KWDconstructor`END`PUN()`END`PLN `END`PUN:`END`PLN `END`KWDsuper`END`PUN()`END`PLN\n' + + '\n' + + '`END`STR"\\\"true\\\""`END`PLN\n' + + '`END`STR\'a\'`END`PLN\n' + + '\n' + + '`END`STR"""\n' + + 'aaaaaaaaaaa\n' + + '"""`END`PLN\n' + + '\n' + + '`END`LITloop@`END`PLN `END`KWDfor`END`PUN()`END`PLN\n' + + '\n' + + '`END`KWDbreak`END`PLN `END`LIT@loop`END`PLN\n' + + '\n' + + '`END`KWDenum class`END`PLN `END`TYP\`true\``END`PLN\n' + + '\n' + + '`END`KWDdata class`END`PLN `END`TYPPerson`END`PUN(`END`KWDval`END`PLN name`END`PUN:`END`PLN `END`TYPString`END`PUN)`END`PLN\n' + + '\n' + + '`END`KWDenum class`END`PLN `END`TYPSize`END`PLN `END`PUN{`END`PLN\n' + + ' BIG`END`PUN,`END`PLN MEDIUM`END`PUN,`END`PLN SMALL\n' + + '`END`PUN}`END`PLN\n' + + '\n' + + '`END`KWDclass`END`PLN `END`TYPBall`END`PUN(`END`KWDval`END`PLN color`END`PUN:`END`PLN `END`TYPString`END`PUN,`END`PLN `END`KWDval`END`PLN size`END`PUN:`END`PLN `END`TYPSize`END`PUN)`END`PLN `END`PUN{`END`PLN\n' + + ' `END`KWDcompanion object`END`PLN `END`PUN{}`END`PLN\n' + + '\n' + + ' `END`KWDfun`END`PLN isBig`END`PUN()`END`PLN `END`PUN=`END`PLN size `END`PUN==`END`PLN `END`TYPSize`END`PUN.`END`PLNBIG\n' + + '\n' + + ' `END`KWDval`END`PLN isMedium`END`PUN:`END`PLN `END`TYPBoolean`END`PLN\n' + + ' `END`KWDget`END`PUN()`END`PLN `END`PUN=`END`PLN size `END`PUN==`END`PLN `END`TYPSize`END`PUN.`END`PLNMEDIUM\n' + + '`END`PUN}`END`PLN\n' + + '\n' + + '`END`KWDfun`END`PLN `END`TYPBoolean`END`PUN?.`END`PLNisNull`END`PUN():`END`PLN `END`TYPBoolean`END`PLN `END`PUN=`END`PLN `END`KWDthis`END`PLN `END`PUN==`END`PLN `END`LITnull`END`PLN\n' + + '\n' + + '`END`KWDfun`END`PLN `END`TYPBoolean`END`PUN?.`END`PLNgetOrThrow`END`PUN():`END`PLN `END`TYPBoolean`END`PLN `END`PUN=`END`PLN `END`KWDthis`END`PLN `END`PUN?:`END`PLN `END`KWDthrow`END`PLN `END`TYPException`END`PUN()`END' + ), llvm: ( '`COM; Declare the string constant as a global constant.`END`PLN\n' + '@.str `END`PUN=`END`PLN `END`KWDprivate`END`PLN `END`KWDunnamed_addr`END`PLN `END`KWDconstant`END`PLN `END`PUN[`END`LIT13`END`PLN `END`KWDx`END`PLN `END`KWDi8`END`PUN]`END`PLN `END`KWDc`END`STR"hello world\\0A\\00"`END`PLN\n' +