1
0
mirror of https://github.com/alecthomas/chroma.git synced 2025-03-17 20:58:08 +02:00

Kotlin improvements around string interpolation, escaping, and generics (#392)

This commit is contained in:
Pedro Loureiro 2020-08-28 01:26:29 +01:00 committed by GitHub
parent 86ebaf326b
commit fb0b720d14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 438 additions and 16 deletions

View File

@ -28,29 +28,67 @@ var Kotlin = internal.Register(MustNewLexer(
{`%=|&&|\*=|\+\+|\+=|--|-=|->|\.\.|\/=|::|<=|==|>=|!!|!=|\|\||\?[:.]`, Operator, nil},
{`[~!%^&*()+=|\[\]:;,.<>\/?-]`, Punctuation, nil},
{`[{}]`, Punctuation, nil},
{`"""[^"]*"""`, LiteralString, nil},
{`"(\\\\|\\"|[^"\n])*["\n]`, LiteralString, nil},
{`"""`, LiteralString, Push("rawstring")},
{`"`, LiteralStringDouble, Push("string")},
{`(')(\\u[0-9a-fA-F]{4})(')`, ByGroups(LiteralStringChar, LiteralStringEscape, LiteralStringChar), nil},
{`'\\.'|'[^\\]'`, LiteralStringChar, nil},
{`0[xX][0-9a-fA-F]+[Uu]?[Ll]?|[0-9]+(\.[0-9]*)?([eE][+-][0-9]+)?[fF]?[Uu]?[Ll]?`, LiteralNumber, nil},
{`(companion)(\s+)(object)`, ByGroups(Keyword, Text, Keyword), nil},
{`(class|interface|object)(\s+)`, ByGroups(Keyword, Text), Push("class")},
{`(package|import)(\s+)`, ByGroups(Keyword, Text), Push("package")},
{`(val|var)(\s+)`, ByGroups(Keyword, Text), Push("property")},
{`(fun)(\s+)(<[^>]*>\s+)?`, ByGroups(Keyword, Text, Text), Push("function")},
{`(fun)(\s+)`, ByGroups(Keyword, Text), Push("function")},
{`(abstract|actual|annotation|as|as\?|break|by|catch|class|companion|const|constructor|continue|crossinline|data|delegate|do|dynamic|else|enum|expect|external|false|field|file|final|finally|for|fun|get|if|import|in|infix|init|inline|inner|interface|internal|is|it|lateinit|noinline|null|object|open|operator|out|override|package|param|private|property|protected|public|receiver|reified|return|sealed|set|setparam|super|suspend|tailrec|this|throw|true|try|typealias|typeof|val|var|vararg|when|where|while)\b`, Keyword, nil},
{"(@?[" + kotlinIdentifier + "]*`)", Name, nil},
{`@[` + kotlinIdentifier + `]+`, NameDecorator, nil},
{`[` + kotlinIdentifier + `]+`, Name, nil},
},
"package": {
{`\S+`, NameNamespace, Pop(1)},
},
"class": {
{"(@?[" + kotlinIdentifier + "]*`)", NameClass, Pop(1)},
// \x60 is the back tick character (`)
{`\x60[^\x60]+?\x60`, NameClass, Pop(1)},
{`[` + kotlinIdentifier + `]+`, NameClass, Pop(1)},
},
"property": {
{"(@?[" + kotlinIdentifier + " ]*`)", NameProperty, Pop(1)},
{`\x60[^\x60]+?\x60`, NameProperty, Pop(1)},
{`[` + kotlinIdentifier + `]+`, NameProperty, Pop(1)},
},
"generics-specification": {
{`<`, Punctuation, Push("generics-specification")}, // required for generics inside generics e.g. <T : List<Int> >
{`>`, Punctuation, Pop(1)},
{`[,:*?]`, Punctuation, nil},
{`(in|out|reified)`, Keyword, nil},
{`\x60[^\x60]+?\x60`, NameClass, nil},
{`[` + kotlinIdentifier + `]+`, NameClass, nil},
{`\s+`, Text, nil},
},
"function": {
{"(@?[" + kotlinIdentifier + " ]*`)", NameFunction, Pop(1)},
{`<`, Punctuation, Push("generics-specification")},
{`\x60[^\x60]+?\x60`, NameFunction, Pop(1)},
{`[` + kotlinIdentifier + `]+`, NameFunction, Pop(1)},
{`\s+`, Text, nil},
},
"rawstring": {
// raw strings don't allow character escaping
{`"""`, LiteralString, Pop(1)},
{`(?:[^$"]+|\"{1,2}[^"])+`, LiteralString, nil},
Include("string-interpol"),
// remaining dollar signs are just a string
{`\$`, LiteralString, nil},
},
"string": {
{`\\[tbnr'"\\\$]`, LiteralStringEscape, nil},
{`\\u[0-9a-fA-F]{4}`, LiteralStringEscape, nil},
{`"`, LiteralStringDouble, Pop(1)},
Include("string-interpol"),
{`[^\n\\"$]+`, LiteralStringDouble, nil},
// remaining dollar signs are just a string
{`\$`, LiteralStringDouble, nil},
},
"string-interpol": {
{`\$[` + kotlinIdentifier + `]+`, LiteralStringInterpol, nil},
{`\${[^}\n]*}`, LiteralStringInterpol, nil},
},
},
))

View File

@ -21,6 +21,23 @@ fun nullable2(nullable: String?): Int = nullable?.length ?: run {
1 + 2
}
val rawStringWithQuotes = """
Hello "example" ${1 + 2}
And now { Just the braces }
Escapes here don't work so this is just text \t \n \u1234 $ \$
"""
fun returnsSomething(): Int {
return "".length
}
fun returnsSomethingElse(): Int = "\\\n".length
val character = '"'
val escapedCharacter = '\"'
// escaping a double quote character inside a character is optional
val stringWithSingleQuote = "'"
typealias MySecretAlias<A, B> = (A, B) -> Unit
val impl : MySecretAlias<Int, Int> = { a, _ -> Unit }
@ -66,6 +83,42 @@ fun moreOperators(arg: Any?) {
println(arg === Unit)
}
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION,
AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION)
@Retention(AnnotationRetention.SOURCE)
annotation class Annotated
@Annotated class A {
@Annotated fun a(
@Annotated param: Int
) {
@Annotated val y = 0
}
}
open class TUpper
fun <T: TUpper, R: Any?> generic() = 123
class Holder <in A, out B, C: TUpper>
class Holder2 <T>
var holder1: Holder<Int, String, *>? = null
class Some(
val holder2: Holder<Int, String, *>? = null
) {
var holder3: Holder<Int, String, *>? = null
fun example() {
var holder4: Holder<Int, String, *>? = null
}
}
fun <T : Comparable<T>> sort(list: List<T>) {
}
class X {
companion object {
}

View File

@ -27,14 +27,12 @@
{"type":"Text","value":"\n "},
{"type":"Keyword","value":"val"},
{"type":"Text","value":" "},
{"type":"Error","value":"` + \""},
{"type":"NameProperty","value":"with"},
{"type":"NameProperty","value":"` + \"with spaces\" + `"},
{"type":"Text","value":" "},
{"type":"Name","value":"spaces"},
{"type":"LiteralString","value":"\" + ` = \""},
{"type":"Name","value":"hello"},
{"type":"LiteralString","value":"\"\n"},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"="},
{"type":"Text","value":" "},
{"type":"LiteralStringDouble","value":"\"hello\""},
{"type":"Text","value":"\n "},
{"type":"Keyword","value":"val"},
{"type":"Text","value":" "},
{"type":"NameProperty","value":"multiline"},
@ -130,6 +128,73 @@
{"type":"Text","value":"\n"},
{"type":"Punctuation","value":"}"},
{"type":"Text","value":"\n\n"},
{"type":"Keyword","value":"val"},
{"type":"Text","value":" "},
{"type":"NameProperty","value":"rawStringWithQuotes"},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"="},
{"type":"Text","value":" "},
{"type":"LiteralString","value":"\"\"\"\nHello \"example\" "},
{"type":"LiteralStringInterpol","value":"${1 + 2}"},
{"type":"LiteralString","value":"\nAnd now { Just the braces }\nEscapes here don't work so this is just text \\t \\n \\u1234 $ \\$\n\"\"\""},
{"type":"Text","value":"\n\n"},
{"type":"Keyword","value":"fun"},
{"type":"Text","value":" "},
{"type":"NameFunction","value":"returnsSomething"},
{"type":"Punctuation","value":"():"},
{"type":"Text","value":" "},
{"type":"Name","value":"Int"},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"{"},
{"type":"Text","value":"\n "},
{"type":"Keyword","value":"return"},
{"type":"Text","value":" "},
{"type":"LiteralStringDouble","value":"\"\""},
{"type":"Punctuation","value":"."},
{"type":"Name","value":"length"},
{"type":"Text","value":"\n"},
{"type":"Punctuation","value":"}"},
{"type":"Text","value":"\n\n"},
{"type":"Keyword","value":"fun"},
{"type":"Text","value":" "},
{"type":"NameFunction","value":"returnsSomethingElse"},
{"type":"Punctuation","value":"():"},
{"type":"Text","value":" "},
{"type":"Name","value":"Int"},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"="},
{"type":"Text","value":" "},
{"type":"LiteralStringDouble","value":"\""},
{"type":"LiteralStringEscape","value":"\\\\\\n"},
{"type":"LiteralStringDouble","value":"\""},
{"type":"Punctuation","value":"."},
{"type":"Name","value":"length"},
{"type":"Text","value":"\n\n"},
{"type":"Keyword","value":"val"},
{"type":"Text","value":" "},
{"type":"NameProperty","value":"character"},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"="},
{"type":"Text","value":" "},
{"type":"LiteralStringChar","value":"'\"'"},
{"type":"Text","value":"\n"},
{"type":"Keyword","value":"val"},
{"type":"Text","value":" "},
{"type":"NameProperty","value":"escapedCharacter"},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"="},
{"type":"Text","value":" "},
{"type":"LiteralStringChar","value":"'\\\"'"},
{"type":"Text","value":"\n"},
{"type":"CommentSingle","value":"// escaping a double quote character inside a character is optional\n"},
{"type":"Keyword","value":"val"},
{"type":"Text","value":" "},
{"type":"NameProperty","value":"stringWithSingleQuote"},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"="},
{"type":"Text","value":" "},
{"type":"LiteralStringDouble","value":"\"'\""},
{"type":"Text","value":"\n\n"},
{"type":"Keyword","value":"typealias"},
{"type":"Text","value":" "},
{"type":"Name","value":"MySecretAlias"},
@ -214,7 +279,13 @@
{"type":"Text","value":"\n "},
{"type":"Name","value":"println"},
{"type":"Punctuation","value":"("},
{"type":"LiteralString","value":"\"This is an example a = $a and the sum is ${a + b} ${ A.foo() }\""},
{"type":"LiteralStringDouble","value":"\"This is an example a = "},
{"type":"LiteralStringInterpol","value":"$a"},
{"type":"LiteralStringDouble","value":" and the sum is "},
{"type":"LiteralStringInterpol","value":"${a + b}"},
{"type":"LiteralStringDouble","value":" "},
{"type":"LiteralStringInterpol","value":"${ A.foo() }"},
{"type":"LiteralStringDouble","value":"\""},
{"type":"Punctuation","value":")"},
{"type":"Text","value":"\n "},
{"type":"Name","value":"println"},
@ -415,6 +486,260 @@
{"type":"Text","value":"\n"},
{"type":"Punctuation","value":"}"},
{"type":"Text","value":"\n\n"},
{"type":"NameDecorator","value":"@Target"},
{"type":"Punctuation","value":"("},
{"type":"Name","value":"AnnotationTarget"},
{"type":"Punctuation","value":"."},
{"type":"Name","value":"CLASS"},
{"type":"Punctuation","value":","},
{"type":"Text","value":" "},
{"type":"Name","value":"AnnotationTarget"},
{"type":"Punctuation","value":"."},
{"type":"Name","value":"FUNCTION"},
{"type":"Punctuation","value":","},
{"type":"Text","value":"\n "},
{"type":"Name","value":"AnnotationTarget"},
{"type":"Punctuation","value":"."},
{"type":"Name","value":"VALUE_PARAMETER"},
{"type":"Punctuation","value":","},
{"type":"Text","value":" "},
{"type":"Name","value":"AnnotationTarget"},
{"type":"Punctuation","value":"."},
{"type":"Name","value":"EXPRESSION"},
{"type":"Punctuation","value":")"},
{"type":"Text","value":"\n"},
{"type":"NameDecorator","value":"@Retention"},
{"type":"Punctuation","value":"("},
{"type":"Name","value":"AnnotationRetention"},
{"type":"Punctuation","value":"."},
{"type":"Name","value":"SOURCE"},
{"type":"Punctuation","value":")"},
{"type":"Text","value":"\n"},
{"type":"Keyword","value":"annotation"},
{"type":"Text","value":" "},
{"type":"Keyword","value":"class"},
{"type":"Text","value":" "},
{"type":"NameClass","value":"Annotated"},
{"type":"Text","value":"\n\n"},
{"type":"NameDecorator","value":"@Annotated"},
{"type":"Text","value":" "},
{"type":"Keyword","value":"class"},
{"type":"Text","value":" "},
{"type":"NameClass","value":"A"},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"{"},
{"type":"Text","value":"\n "},
{"type":"NameDecorator","value":"@Annotated"},
{"type":"Text","value":" "},
{"type":"Keyword","value":"fun"},
{"type":"Text","value":" "},
{"type":"NameFunction","value":"a"},
{"type":"Punctuation","value":"("},
{"type":"Text","value":"\n "},
{"type":"NameDecorator","value":"@Annotated"},
{"type":"Text","value":" "},
{"type":"Keyword","value":"param"},
{"type":"Punctuation","value":":"},
{"type":"Text","value":" "},
{"type":"Name","value":"Int"},
{"type":"Text","value":"\n "},
{"type":"Punctuation","value":")"},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"{"},
{"type":"Text","value":"\n\n "},
{"type":"NameDecorator","value":"@Annotated"},
{"type":"Text","value":" "},
{"type":"Keyword","value":"val"},
{"type":"Text","value":" "},
{"type":"NameProperty","value":"y"},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"="},
{"type":"Text","value":" "},
{"type":"LiteralNumber","value":"0"},
{"type":"Text","value":"\n\n "},
{"type":"Punctuation","value":"}"},
{"type":"Text","value":"\n"},
{"type":"Punctuation","value":"}"},
{"type":"Text","value":"\n\n"},
{"type":"Keyword","value":"open"},
{"type":"Text","value":" "},
{"type":"Keyword","value":"class"},
{"type":"Text","value":" "},
{"type":"NameClass","value":"TUpper"},
{"type":"Text","value":"\n"},
{"type":"Keyword","value":"fun"},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"\u003c"},
{"type":"NameClass","value":"T"},
{"type":"Punctuation","value":":"},
{"type":"Text","value":" "},
{"type":"NameClass","value":"TUpper"},
{"type":"Punctuation","value":","},
{"type":"Text","value":" "},
{"type":"NameClass","value":"R"},
{"type":"Punctuation","value":":"},
{"type":"Text","value":" "},
{"type":"NameClass","value":"Any"},
{"type":"Punctuation","value":"?\u003e"},
{"type":"Text","value":" "},
{"type":"NameFunction","value":"generic"},
{"type":"Punctuation","value":"()"},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"="},
{"type":"Text","value":" "},
{"type":"LiteralNumber","value":"123"},
{"type":"Text","value":"\n\n"},
{"type":"Keyword","value":"class"},
{"type":"Text","value":" "},
{"type":"NameClass","value":"Holder"},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"\u003c"},
{"type":"Keyword","value":"in"},
{"type":"Text","value":" "},
{"type":"Name","value":"A"},
{"type":"Punctuation","value":","},
{"type":"Text","value":" "},
{"type":"Keyword","value":"out"},
{"type":"Text","value":" "},
{"type":"Name","value":"B"},
{"type":"Punctuation","value":","},
{"type":"Text","value":" "},
{"type":"Name","value":"C"},
{"type":"Punctuation","value":":"},
{"type":"Text","value":" "},
{"type":"Name","value":"TUpper"},
{"type":"Punctuation","value":"\u003e"},
{"type":"Text","value":"\n\n"},
{"type":"Keyword","value":"class"},
{"type":"Text","value":" "},
{"type":"NameClass","value":"Holder2"},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"\u003c"},
{"type":"Name","value":"T"},
{"type":"Punctuation","value":"\u003e"},
{"type":"Text","value":"\n\n"},
{"type":"Keyword","value":"var"},
{"type":"Text","value":" "},
{"type":"NameProperty","value":"holder1"},
{"type":"Punctuation","value":":"},
{"type":"Text","value":" "},
{"type":"Name","value":"Holder"},
{"type":"Punctuation","value":"\u003c"},
{"type":"Name","value":"Int"},
{"type":"Punctuation","value":","},
{"type":"Text","value":" "},
{"type":"Name","value":"String"},
{"type":"Punctuation","value":","},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"*\u003e?"},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"="},
{"type":"Text","value":" "},
{"type":"Keyword","value":"null"},
{"type":"Text","value":"\n\n"},
{"type":"Keyword","value":"class"},
{"type":"Text","value":" "},
{"type":"NameClass","value":"Some"},
{"type":"Punctuation","value":"("},
{"type":"Text","value":"\n "},
{"type":"Keyword","value":"val"},
{"type":"Text","value":" "},
{"type":"NameProperty","value":"holder2"},
{"type":"Punctuation","value":":"},
{"type":"Text","value":" "},
{"type":"Name","value":"Holder"},
{"type":"Punctuation","value":"\u003c"},
{"type":"Name","value":"Int"},
{"type":"Punctuation","value":","},
{"type":"Text","value":" "},
{"type":"Name","value":"String"},
{"type":"Punctuation","value":","},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"*\u003e?"},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"="},
{"type":"Text","value":" "},
{"type":"Keyword","value":"null"},
{"type":"Text","value":"\n"},
{"type":"Punctuation","value":")"},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"{"},
{"type":"Text","value":"\n "},
{"type":"Keyword","value":"var"},
{"type":"Text","value":" "},
{"type":"NameProperty","value":"holder3"},
{"type":"Punctuation","value":":"},
{"type":"Text","value":" "},
{"type":"Name","value":"Holder"},
{"type":"Punctuation","value":"\u003c"},
{"type":"Name","value":"Int"},
{"type":"Punctuation","value":","},
{"type":"Text","value":" "},
{"type":"Name","value":"String"},
{"type":"Punctuation","value":","},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"*\u003e?"},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"="},
{"type":"Text","value":" "},
{"type":"Keyword","value":"null"},
{"type":"Text","value":"\n "},
{"type":"Keyword","value":"fun"},
{"type":"Text","value":" "},
{"type":"NameFunction","value":"example"},
{"type":"Punctuation","value":"()"},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"{"},
{"type":"Text","value":"\n "},
{"type":"Keyword","value":"var"},
{"type":"Text","value":" "},
{"type":"NameProperty","value":"holder4"},
{"type":"Punctuation","value":":"},
{"type":"Text","value":" "},
{"type":"Name","value":"Holder"},
{"type":"Punctuation","value":"\u003c"},
{"type":"Name","value":"Int"},
{"type":"Punctuation","value":","},
{"type":"Text","value":" "},
{"type":"Name","value":"String"},
{"type":"Punctuation","value":","},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"*\u003e?"},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"="},
{"type":"Text","value":" "},
{"type":"Keyword","value":"null"},
{"type":"Text","value":"\n "},
{"type":"Punctuation","value":"}"},
{"type":"Text","value":"\n"},
{"type":"Punctuation","value":"}"},
{"type":"Text","value":"\n"},
{"type":"Keyword","value":"fun"},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"\u003c"},
{"type":"NameClass","value":"T"},
{"type":"Text","value":" "},
{"type":"Punctuation","value":":"},
{"type":"Text","value":" "},
{"type":"NameClass","value":"Comparable"},
{"type":"Punctuation","value":"\u003c"},
{"type":"NameClass","value":"T"},
{"type":"Punctuation","value":"\u003e\u003e"},
{"type":"Text","value":" "},
{"type":"NameFunction","value":"sort"},
{"type":"Punctuation","value":"("},
{"type":"Name","value":"list"},
{"type":"Punctuation","value":":"},
{"type":"Text","value":" "},
{"type":"Name","value":"List"},
{"type":"Punctuation","value":"\u003c"},
{"type":"Name","value":"T"},
{"type":"Punctuation","value":"\u003e)"},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"{"},
{"type":"Text","value":"\n \n"},
{"type":"Punctuation","value":"}"},
{"type":"Text","value":"\n\n"},
{"type":"Keyword","value":"class"},
{"type":"Text","value":" "},
{"type":"NameClass","value":"X"},
@ -434,7 +759,13 @@
{"type":"Keyword","value":"inline"},
{"type":"Text","value":" "},
{"type":"Keyword","value":"fun"},
{"type":"Text","value":" \u003creified T\u003e "},
{"type":"Text","value":" "},
{"type":"Punctuation","value":"\u003c"},
{"type":"Keyword","value":"reified"},
{"type":"Text","value":" "},
{"type":"NameClass","value":"T"},
{"type":"Punctuation","value":"\u003e"},
{"type":"Text","value":" "},
{"type":"NameFunction","value":"generic"},
{"type":"Punctuation","value":"("},
{"type":"Name","value":"t"},