diff --git a/components.js b/components.js index 7a221fc78a..5bfd705636 100644 --- a/components.js +++ b/components.js @@ -266,6 +266,11 @@ var components = { "title": "Keyman", "owner": "mcdurdin" }, + "kotlin": { + "title": "Kotlin", + "require": "clike", + "owner": "Golmote" + }, "latex": { "title": "LaTeX", "owner": "japborst" diff --git a/components/prism-kotlin.js b/components/prism-kotlin.js new file mode 100644 index 0000000000..e473c2fbf8 --- /dev/null +++ b/components/prism-kotlin.js @@ -0,0 +1,68 @@ +(function (Prism) { + Prism.languages.kotlin = Prism.languages.extend('clike', { + 'keyword': { + // The lookbehind prevents wrong highlighting of e.g. kotlin.properties.get + pattern: /(^|[^.])\b(?:abstract|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|else|enum|final|finally|for|fun|get|if|import|in|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|out|override|package|private|protected|public|reified|return|sealed|set|super|tailrec|this|throw|to|try|val|var|when|where|while)\b/, + lookbehind: true + }, + 'function': [ + /\w+(?=\s*\()/, + { + pattern: /(\.)\w+(?=\s*\{)/, + lookbehind: true + } + ], + 'number': /\b(?:0[bx][\da-fA-F]+|\d+(?:\.\d+)?(?:e[+-]?\d+)?[fFL]?)\b/, + 'operator': /\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\/*%<>]=?|[?:]:?|\.\.|&&|\|\||\b(?:and|inv|or|shl|shr|ushr|xor)\b/ + }); + + delete Prism.languages.kotlin["class-name"]; + + Prism.languages.insertBefore('kotlin', 'string', { + 'raw-string': { + pattern: /(["'])\1\1[\s\S]*?\1{3}/, + alias: 'string' + // See interpolation below + } + }); + Prism.languages.insertBefore('kotlin', 'keyword', { + 'annotation': { + pattern: /\B@(?:\w+:)?(?:[A-Z]\w*|\[[^\]]+\])/, + alias: 'builtin' + } + }); + Prism.languages.insertBefore('kotlin', 'function', { + 'label': { + pattern: /\w+@|@\w+/, + alias: 'symbol' + } + }); + + var interpolation = [ + { + pattern: /\$\{[^}]+\}/, + inside: { + delimiter: { + pattern: /^\$\{|\}$/, + alias: 'variable' + }, + rest: Prism.util.clone(Prism.languages.kotlin) + } + }, + { + pattern: /\$\w+/, + alias: 'variable' + } + ]; + + Prism.languages.kotlin['string'] = { + pattern: Prism.languages.kotlin['string'], + inside: { + interpolation: interpolation + } + }; + Prism.languages.kotlin['raw-string'].inside = { + interpolation: interpolation + }; + +}(Prism)); \ No newline at end of file diff --git a/components/prism-kotlin.min.js b/components/prism-kotlin.min.js new file mode 100644 index 0000000000..dce90b6446 --- /dev/null +++ b/components/prism-kotlin.min.js @@ -0,0 +1 @@ +!function(n){n.languages.kotlin=n.languages.extend("clike",{keyword:{pattern:/(^|[^.])\b(?:abstract|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|else|enum|final|finally|for|fun|get|if|import|in|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|out|override|package|private|protected|public|reified|return|sealed|set|super|tailrec|this|throw|to|try|val|var|when|where|while)\b/,lookbehind:!0},"function":[/\w+(?=\s*\()/,{pattern:/(\.)\w+(?=\s*\{)/,lookbehind:!0}],number:/\b(?:0[bx][\da-fA-F]+|\d+(?:\.\d+)?(?:e[+-]?\d+)?[fFL]?)\b/,operator:/\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\/*%<>]=?|[?:]:?|\.\.|&&|\|\||\b(?:and|inv|or|shl|shr|ushr|xor)\b/}),delete n.languages.kotlin["class-name"],n.languages.insertBefore("kotlin","string",{"raw-string":{pattern:/(["'])\1\1[\s\S]*?\1{3}/,alias:"string"}}),n.languages.insertBefore("kotlin","keyword",{annotation:{pattern:/\B@(?:\w+:)?(?:[A-Z]\w*|\[[^\]]+\])/,alias:"builtin"}}),n.languages.insertBefore("kotlin","function",{label:{pattern:/\w+@|@\w+/,alias:"symbol"}});var e=[{pattern:/\$\{[^}]+\}/,inside:{delimiter:{pattern:/^\$\{|\}$/,alias:"variable"},rest:n.util.clone(n.languages.kotlin)}},{pattern:/\$\w+/,alias:"variable"}];n.languages.kotlin.string={pattern:n.languages.kotlin.string,inside:{interpolation:e}},n.languages.kotlin["raw-string"].inside={interpolation:e}}(Prism); \ No newline at end of file diff --git a/examples/prism-kotlin.html b/examples/prism-kotlin.html new file mode 100644 index 0000000000..c996624187 --- /dev/null +++ b/examples/prism-kotlin.html @@ -0,0 +1,147 @@ +

Kotlin

+

To use this language, use the class "language-kotlin".

+ +

Numbers

+
123
+123L
+0x0F
+0b00001011
+123.5
+123.5e10
+123.5f
+123.5F
+ +

Strings and interpolation

+
'2'
+'\uFF00'
+'\''
+
+"foo $bar \"baz"
+"""
+foo ${40 + 2}
+baz${bar()}
+"""
+ +

Labels

+
loop@ for (i in 1..100) {
+  for (j in 1..100) {
+    if (...)
+      break@loop
+  }
+}
+ +

Annotations

+
public class MyTest {
+    lateinit var subject: TestSubject
+
+    @SetUp fun setup() {
+        subject = TestSubject()
+    }
+
+    @Test fun test() {
+        subject.method()  // dereference directly
+    }
+}
+ +

Full example

+
package com.example.html
+
+interface Element {
+    fun render(builder: StringBuilder, indent: String)
+
+    override fun toString(): String {
+        val builder = StringBuilder()
+        render(builder, "")
+        return builder.toString()
+    }
+}
+
+class TextElement(val text: String): Element {
+    override fun render(builder: StringBuilder, indent: String) {
+        builder.append("$indent$text\n")
+    }
+}
+
+abstract class Tag(val name: String): Element {
+    val children = arrayListOf<Element>()
+    val attributes = hashMapOf<String, String>()
+
+    protected fun initTag<T: Element>(tag: T, init: T.() -> Unit): T {
+        tag.init()
+        children.add(tag)
+        return tag
+    }
+
+    override fun render(builder: StringBuilder, indent: String) {
+        builder.append("$indent<$name${renderAttributes()}>\n")
+        for (c in children) {
+            c.render(builder, indent + "  ")
+        }
+        builder.append("$indent</$name>\n")
+    }
+
+    private fun renderAttributes(): String? {
+        val builder = StringBuilder()
+        for (a in attributes.keySet()) {
+            builder.append(" $a=\"${attributes[a]}\"")
+        }
+        return builder.toString()
+    }
+}
+
+abstract class TagWithText(name: String): Tag(name) {
+    operator fun String.plus() {
+        children.add(TextElement(this))
+    }
+}
+
+class HTML(): TagWithText("html") {
+    fun head(init: Head.() -> Unit) = initTag(Head(), init)
+
+    fun body(init: Body.() -> Unit) = initTag(Body(), init)
+}
+
+class Head(): TagWithText("head") {
+    fun title(init: Title.() -> Unit) = initTag(Title(), init)
+}
+
+class Title(): TagWithText("title")
+
+abstract class BodyTag(name: String): TagWithText(name) {
+    fun b(init: B.() -> Unit) = initTag(B(), init)
+    fun p(init: P.() -> Unit) = initTag(P(), init)
+    fun h1(init: H1.() -> Unit) = initTag(H1(), init)
+    fun a(href: String, init: A.() -> Unit) {
+        val a = initTag(A(), init)
+        a.href = href
+    }
+}
+
+class Body(): BodyTag("body")
+
+class B(): BodyTag("b")
+class P(): BodyTag("p")
+class H1(): BodyTag("h1")
+class A(): BodyTag("a") {
+    public var href: String
+        get() = attributes["href"]!!
+        set(value) {
+            attributes["href"] = value
+        }
+}
+
+fun html(init: HTML.() -> Unit): HTML {
+    val html = HTML()
+    html.init()
+    return html
+}
+ +

Known failures

+

There are certain edge cases where Prism will fail. + There are always such cases in every regex-based syntax highlighter. + However, Prism dares to be open and honest about them. + If a failure is listed here, it doesn’t mean it will never be fixed. This is more of a “known bugs” list, just with a certain type of bug. +

+ +

Comment-like substrings

+
"foo /* bar */";
\ No newline at end of file diff --git a/plugins/autoloader/prism-autoloader.js b/plugins/autoloader/prism-autoloader.js index 0d04b72bc4..68a981ce7a 100644 --- a/plugins/autoloader/prism-autoloader.js +++ b/plugins/autoloader/prism-autoloader.js @@ -4,7 +4,7 @@ } // The dependencies map is built automatically with gulp - var lang_dependencies = /*languages_placeholder[*/{"javascript":"clike","actionscript":"javascript","aspnet":"markup","bison":"c","c":"clike","csharp":"clike","cpp":"c","coffeescript":"javascript","crystal":"ruby","css-extras":"css","d":"clike","dart":"clike","fsharp":"clike","glsl":"clike","go":"clike","groovy":"clike","haml":"ruby","handlebars":"markup","haxe":"clike","jade":"javascript","java":"clike","less":"css","markdown":"markup","nginx":"clike","objectivec":"c","parser":"markup","php":"clike","php-extras":"php","processing":"clike","qore":"clike","jsx":["markup","javascript"],"ruby":"clike","sass":"css","scss":"css","scala":"java","smarty":"markup","swift":"clike","textile":"markup","twig":"markup","typescript":"javascript","wiki":"markup"}/*]*/; + var lang_dependencies = /*languages_placeholder[*/{"javascript":"clike","actionscript":"javascript","aspnet":"markup","bison":"c","c":"clike","csharp":"clike","cpp":"c","coffeescript":"javascript","crystal":"ruby","css-extras":"css","d":"clike","dart":"clike","fsharp":"clike","glsl":"clike","go":"clike","groovy":"clike","haml":"ruby","handlebars":"markup","haxe":"clike","jade":"javascript","java":"clike","kotlin":"clike","less":"css","markdown":"markup","nginx":"clike","objectivec":"c","parser":"markup","php":"clike","php-extras":"php","processing":"clike","qore":"clike","jsx":["markup","javascript"],"ruby":"clike","sass":"css","scss":"css","scala":"java","smarty":"markup","swift":"clike","textile":"markup","twig":"markup","typescript":"javascript","wiki":"markup"}/*]*/; var lang_data = {}; diff --git a/plugins/autoloader/prism-autoloader.min.js b/plugins/autoloader/prism-autoloader.min.js index ef40ff60e6..3dffdf1e72 100644 --- a/plugins/autoloader/prism-autoloader.min.js +++ b/plugins/autoloader/prism-autoloader.min.js @@ -1 +1 @@ -!function(){if("undefined"!=typeof self&&self.Prism&&self.document&&document.createElement){var e={javascript:"clike",actionscript:"javascript",aspnet:"markup",bison:"c",c:"clike",csharp:"clike",cpp:"c",coffeescript:"javascript",crystal:"ruby","css-extras":"css",d:"clike",dart:"clike",fsharp:"clike",glsl:"clike",go:"clike",groovy:"clike",haml:"ruby",handlebars:"markup",haxe:"clike",jade:"javascript",java:"clike",less:"css",markdown:"markup",nginx:"clike",objectivec:"c",parser:"markup",php:"clike","php-extras":"php",processing:"clike",qore:"clike",jsx:["markup","javascript"],ruby:"clike",sass:"css",scss:"css",scala:"java",smarty:"markup",swift:"clike",textile:"markup",twig:"markup",typescript:"javascript",wiki:"markup"},c={},a=Prism.plugins.autoloader={languages_path:"components/",use_minified:!0},s=function(e,c,a){var s=document.createElement("script");s.src=e,s.async=!0,s.onload=function(){document.body.removeChild(s),c&&c()},s.onerror=function(){document.body.removeChild(s),a&&a()},document.body.appendChild(s)},r=function(e){return a.languages_path+"prism-"+e+(a.use_minified?".min":"")+".js"},n=function(e,a){var s=c[e];s||(s=c[e]={});var r=a.getAttribute("data-dependencies");!r&&a.parentNode&&"pre"===a.parentNode.tagName.toLowerCase()&&(r=a.parentNode.getAttribute("data-dependencies")),r=r?r.split(/\s*,\s*/g):[],i(r,function(){t(e,function(){Prism.highlightElement(a)})})},i=function(e,c,a){"string"==typeof e&&(e=[e]);var s=0,r=e.length,n=function(){r>s?t(e[s],function(){s++,n()},function(){a&&a(e[s])}):s===r&&c&&c(e)};n()},t=function(a,n,t){var u=function(){var e=!1;a.indexOf("!")>=0&&(e=!0,a=a.replace("!",""));var i=c[a];if(i||(i=c[a]={}),n&&(i.success_callbacks||(i.success_callbacks=[]),i.success_callbacks.push(n)),t&&(i.error_callbacks||(i.error_callbacks=[]),i.error_callbacks.push(t)),!e&&Prism.languages[a])l(a);else if(!e&&i.error)o(a);else if(e||!i.loading){i.loading=!0;var u=r(a);s(u,function(){i.loading=!1,l(a)},function(){i.loading=!1,i.error=!0,o(a)})}},p=e[a];p&&p.length?i(p,u):u()},l=function(e){c[e]&&c[e].success_callbacks&&c[e].success_callbacks.length&&c[e].success_callbacks.forEach(function(c){c(e)})},o=function(e){c[e]&&c[e].error_callbacks&&c[e].error_callbacks.length&&c[e].error_callbacks.forEach(function(c){c(e)})};Prism.hooks.add("complete",function(e){e.element&&e.language&&!e.grammar&&n(e.language,e.element)})}}(); \ No newline at end of file +!function(){if("undefined"!=typeof self&&self.Prism&&self.document&&document.createElement){var e={javascript:"clike",actionscript:"javascript",aspnet:"markup",bison:"c",c:"clike",csharp:"clike",cpp:"c",coffeescript:"javascript",crystal:"ruby","css-extras":"css",d:"clike",dart:"clike",fsharp:"clike",glsl:"clike",go:"clike",groovy:"clike",haml:"ruby",handlebars:"markup",haxe:"clike",jade:"javascript",java:"clike",kotlin:"clike",less:"css",markdown:"markup",nginx:"clike",objectivec:"c",parser:"markup",php:"clike","php-extras":"php",processing:"clike",qore:"clike",jsx:["markup","javascript"],ruby:"clike",sass:"css",scss:"css",scala:"java",smarty:"markup",swift:"clike",textile:"markup",twig:"markup",typescript:"javascript",wiki:"markup"},c={},a=Prism.plugins.autoloader={languages_path:"components/",use_minified:!0},s=function(e,c,a){var s=document.createElement("script");s.src=e,s.async=!0,s.onload=function(){document.body.removeChild(s),c&&c()},s.onerror=function(){document.body.removeChild(s),a&&a()},document.body.appendChild(s)},r=function(e){return a.languages_path+"prism-"+e+(a.use_minified?".min":"")+".js"},n=function(e,a){var s=c[e];s||(s=c[e]={});var r=a.getAttribute("data-dependencies");!r&&a.parentNode&&"pre"===a.parentNode.tagName.toLowerCase()&&(r=a.parentNode.getAttribute("data-dependencies")),r=r?r.split(/\s*,\s*/g):[],i(r,function(){t(e,function(){Prism.highlightElement(a)})})},i=function(e,c,a){"string"==typeof e&&(e=[e]);var s=0,r=e.length,n=function(){r>s?t(e[s],function(){s++,n()},function(){a&&a(e[s])}):s===r&&c&&c(e)};n()},t=function(a,n,t){var u=function(){var e=!1;a.indexOf("!")>=0&&(e=!0,a=a.replace("!",""));var i=c[a];if(i||(i=c[a]={}),n&&(i.success_callbacks||(i.success_callbacks=[]),i.success_callbacks.push(n)),t&&(i.error_callbacks||(i.error_callbacks=[]),i.error_callbacks.push(t)),!e&&Prism.languages[a])l(a);else if(!e&&i.error)o(a);else if(e||!i.loading){i.loading=!0;var u=r(a);s(u,function(){i.loading=!1,l(a)},function(){i.loading=!1,i.error=!0,o(a)})}},p=e[a];p&&p.length?i(p,u):u()},l=function(e){c[e]&&c[e].success_callbacks&&c[e].success_callbacks.length&&c[e].success_callbacks.forEach(function(c){c(e)})},o=function(e){c[e]&&c[e].error_callbacks&&c[e].error_callbacks.length&&c[e].error_callbacks.forEach(function(c){c(e)})};Prism.hooks.add("complete",function(e){e.element&&e.language&&!e.grammar&&n(e.language,e.element)})}}(); \ No newline at end of file diff --git a/tests/languages/kotlin/annotation_feature.test b/tests/languages/kotlin/annotation_feature.test new file mode 100644 index 0000000000..05c138556d --- /dev/null +++ b/tests/languages/kotlin/annotation_feature.test @@ -0,0 +1,21 @@ +@Deprecated(SUBSYSTEM_DEPRECATED) +@SetUp +@Suppress +@field:Ann +@file:JvmName +@set:[Inject VisibleForTesting] + +---------------------------------------------------- + +[ + ["annotation", "@Deprecated"], ["punctuation", "("], "SUBSYSTEM_DEPRECATED", ["punctuation", ")"], + ["annotation", "@SetUp"], + ["annotation", "@Suppress"], + ["annotation", "@field:Ann"], + ["annotation", "@file:JvmName"], + ["annotation", "@set:[Inject VisibleForTesting]"] +] + +---------------------------------------------------- + +Checks for annotations. \ No newline at end of file diff --git a/tests/languages/kotlin/function_feature.test b/tests/languages/kotlin/function_feature.test new file mode 100644 index 0000000000..8bfd2b2261 --- /dev/null +++ b/tests/languages/kotlin/function_feature.test @@ -0,0 +1,16 @@ +foo() +foo_Bar_42() +list.filter {} + +---------------------------------------------------- + +[ + ["function", "foo"], ["punctuation", "("], ["punctuation", ")"], + ["function", "foo_Bar_42"], ["punctuation", "("], ["punctuation", ")"], + "\r\nlist", ["punctuation", "."], + ["function", "filter"], ["punctuation", "{"], ["punctuation", "}"] +] + +---------------------------------------------------- + +Checks for functions. \ No newline at end of file diff --git a/tests/languages/kotlin/interpolation_feature.test b/tests/languages/kotlin/interpolation_feature.test new file mode 100644 index 0000000000..0ee8299bf0 --- /dev/null +++ b/tests/languages/kotlin/interpolation_feature.test @@ -0,0 +1,46 @@ +"$foo ${bar} ${'$'} ${foobar()}" +""" +$foo ${bar} +${'$'} ${foobar()} +""" + +---------------------------------------------------- + +[ + ["string", [ + "\"", + ["interpolation", "$foo"], + ["interpolation", [ + ["delimiter", "${"], "bar", ["delimiter", "}"] + ]], + ["interpolation", [ + ["delimiter", "${"], ["string", "'$'"], ["delimiter", "}"] + ]], + ["interpolation", [ + ["delimiter", "${"], + ["function", "foobar"], ["punctuation", "("], ["punctuation", ")"], + ["delimiter", "}"] + ]], + "\"" + ]], + ["raw-string", [ + "\"\"\"\r\n", + ["interpolation", "$foo"], + ["interpolation", [ + ["delimiter", "${"], "bar", ["delimiter", "}"] + ]], + ["interpolation", [ + ["delimiter", "${"], ["string", "'$'"], ["delimiter", "}"] + ]], + ["interpolation", [ + ["delimiter", "${"], + ["function", "foobar"], ["punctuation", "("], ["punctuation", ")"], + ["delimiter", "}"] + ]], + "\r\n\"\"\"" + ]] +] + +---------------------------------------------------- + +Checks for string interpolation. \ No newline at end of file diff --git a/tests/languages/kotlin/keyword_feature.test b/tests/languages/kotlin/keyword_feature.test new file mode 100644 index 0000000000..d8ace30581 --- /dev/null +++ b/tests/languages/kotlin/keyword_feature.test @@ -0,0 +1,121 @@ +abstract +annotation +as +break +by +catch +class +companion +const +constructor +continue +crossinline +data +do +else +enum +final +finally +for +fun +get +if +import +in +init +inline +inner +interface +internal +is +lateinit +noinline +null +object +open +out +override +package +private +protected +public +reified +return +sealed +set +super +tailrec +this +throw +to +try +val +var +when +where +while + +---------------------------------------------------- + +[ + ["keyword", "abstract"], + ["keyword", "annotation"], + ["keyword", "as"], + ["keyword", "break"], + ["keyword", "by"], + ["keyword", "catch"], + ["keyword", "class"], + ["keyword", "companion"], + ["keyword", "const"], + ["keyword", "constructor"], + ["keyword", "continue"], + ["keyword", "crossinline"], + ["keyword", "data"], + ["keyword", "do"], + ["keyword", "else"], + ["keyword", "enum"], + ["keyword", "final"], + ["keyword", "finally"], + ["keyword", "for"], + ["keyword", "fun"], + ["keyword", "get"], + ["keyword", "if"], + ["keyword", "import"], + ["keyword", "in"], + ["keyword", "init"], + ["keyword", "inline"], + ["keyword", "inner"], + ["keyword", "interface"], + ["keyword", "internal"], + ["keyword", "is"], + ["keyword", "lateinit"], + ["keyword", "noinline"], + ["keyword", "null"], + ["keyword", "object"], + ["keyword", "open"], + ["keyword", "out"], + ["keyword", "override"], + ["keyword", "package"], + ["keyword", "private"], + ["keyword", "protected"], + ["keyword", "public"], + ["keyword", "reified"], + ["keyword", "return"], + ["keyword", "sealed"], + ["keyword", "set"], + ["keyword", "super"], + ["keyword", "tailrec"], + ["keyword", "this"], + ["keyword", "throw"], + ["keyword", "to"], + ["keyword", "try"], + ["keyword", "val"], + ["keyword", "var"], + ["keyword", "when"], + ["keyword", "where"], + ["keyword", "while"] +] + +---------------------------------------------------- + +Checks for keywords. \ No newline at end of file diff --git a/tests/languages/kotlin/label_feature.test b/tests/languages/kotlin/label_feature.test new file mode 100644 index 0000000000..fa6226603a --- /dev/null +++ b/tests/languages/kotlin/label_feature.test @@ -0,0 +1,15 @@ +loop@ +break@loop +return@forEach + +---------------------------------------------------- + +[ + ["label", "loop@"], + ["keyword", "break"], ["label", "@loop"], + ["keyword", "return"], ["label", "@forEach"] +] + +---------------------------------------------------- + +Checks for labels. \ No newline at end of file diff --git a/tests/languages/kotlin/number_feature.test b/tests/languages/kotlin/number_feature.test new file mode 100644 index 0000000000..df21736c63 --- /dev/null +++ b/tests/languages/kotlin/number_feature.test @@ -0,0 +1,29 @@ +123 +123L +0x0F +0b00001011 +123.5 +123.5e10 +123.5e-10 +123.5e+10 +123.5f +123.5F + +---------------------------------------------------- + +[ + ["number", "123"], + ["number", "123L"], + ["number", "0x0F"], + ["number", "0b00001011"], + ["number", "123.5"], + ["number", "123.5e10"], + ["number", "123.5e-10"], + ["number", "123.5e+10"], + ["number", "123.5f"], + ["number", "123.5F"] +] + +---------------------------------------------------- + +Checks for numbers. \ No newline at end of file diff --git a/tests/languages/kotlin/operator_feature.test b/tests/languages/kotlin/operator_feature.test new file mode 100644 index 0000000000..12f0cae315 --- /dev/null +++ b/tests/languages/kotlin/operator_feature.test @@ -0,0 +1,31 @@ ++ ++ += +- -- -= -> += == === +! !! != !== +/ /= * *= +% %= +< <= > >= +? ?: : :: +.. && || +and inv or +shl shr ushr xor + +---------------------------------------------------- + +[ + ["operator", "+"], ["operator", "++"], ["operator", "+="], + ["operator", "-"], ["operator", "--"], ["operator", "-="], ["operator", "->"], + ["operator", "="], ["operator", "=="], ["operator", "==="], + ["operator", "!"], ["operator", "!!"], ["operator", "!="], ["operator", "!=="], + ["operator", "/"], ["operator", "/="], ["operator", "*"], ["operator", "*="], + ["operator", "%"], ["operator", "%="], + ["operator", "<"], ["operator", "<="], ["operator", ">"], ["operator", ">="], + ["operator", "?"], ["operator", "?:"], ["operator", ":"], ["operator", "::"], + ["operator", ".."], ["operator", "&&"], ["operator", "||"], + ["operator", "and"], ["operator", "inv"], ["operator", "or"], + ["operator", "shl"], ["operator", "shr"], ["operator", "ushr"], ["operator", "xor"] +] + +---------------------------------------------------- + +Checks for operators. \ No newline at end of file diff --git a/tests/languages/kotlin/raw-string_feature.test b/tests/languages/kotlin/raw-string_feature.test new file mode 100644 index 0000000000..5a5ca3309b --- /dev/null +++ b/tests/languages/kotlin/raw-string_feature.test @@ -0,0 +1,18 @@ +"""""" +"""Foo "bar"" baz""" +""" +"Foo" +bar +""" + +---------------------------------------------------- + +[ + ["raw-string", ["\"\"\"\"\"\""]], + ["raw-string", ["\"\"\"Foo \"bar\"\" baz\"\"\""]], + ["raw-string", ["\"\"\"\r\n\"Foo\"\r\nbar\r\n\"\"\""]] +] + +---------------------------------------------------- + +Checks for raw strings. \ No newline at end of file