nishtahir / language-kotlin

Textmate language grammar for the Kotlin programming language
Apache License 2.0
12 stars 6 forks source link

Quadruple quotation marks #26

Closed starsep closed 3 years ago

starsep commented 4 years ago

I noticed that https://github.com/JetBrains/kotlin/blob/25a631a1ca8d78f192f4b1a5db2a58d9e886b9b2/compiler/frontend/src/org/jetbrains/kotlin/checkers/diagnostics/TextDiagnostic.kt#L120 isn't properly highlighted. I created simplified version - could this test case be added at the end of literals.test.kt?

  val valueWithQuadrupleQuotes = Regex(""""."""")
//^^^ source.kotlin storage.type.kotlin
//   ^^^^^^^^^^^^^^^^^^^^^^^^^^ source.kotlin
//                             ^ source.kotlin keyword.operator.assignment.kotlin
//                               ^^^^^ source.kotlin entity.name.type.class.kotlin
//                                     ^^^ source.kotlin meta.group.kotlin string.quoted.triple.kotlin punctuation.definition.string.begin.kotlin
//                                        ^^^ source.kotlin meta.group.kotlin string.quoted.triple.kotlin
//                                           ^^^ source.kotlin meta.group.kotlin string.quoted.triple.kotlin punctuation.definition.string.end.kotlin
  val exampleValueAfterQuotes = 42
//^^^ source.kotlin storage.type.kotlin
//   ^^^^^^^^^^^^^^^^^^^^^^^^^ source.kotlin
//                            ^ source.kotlin keyword.operator.assignment.kotlin
//                               ^^ constant.numeric.integer.kotlin

At the moment I don't know to fix this issue, I will try to figure out the grammar rules tomorrow. If you have some idea how to resolve the problem let me know.

nishtahir commented 4 years ago

@starsep I would add a regression for this specifically examples here and optionally add one to literals.

Looks like the issue might be with the triple quote scope greedily matching the first triple quote it can find 🤔. The next quote then gets matched as a double quote begin.

>val valueWithQuadrupleQuotes = Regex(""""."""")
#                                          ^^^ string.quoted.triple.kotlin punctuation.definition.string.end.kotlin
#                                             ^ string.quoted.double.kotlin punctuation.definition.string.begin.kotlin
#                                              ^^ string.quoted.double.kotlin

I think changes need to be made here to non greedily match the triple quote.

xjcl commented 3 years ago

I would really be happy if this could get fixed! I showed my GitHub repo to someone and they were like "Wait this is garbage this is mostly comments??" (because most of the source was highlighted as a string). I've had a very similar with gitinspector before, where a line looking like this:

// Take care of arithmetic operations like +-/*
                                             -- starts a multiline comment in C++

made gitinspector think that all subsequent code was comments. I guess this kind of issue isn't that rare.


I'm also including a permalink to the issue OP cited: https://github.com/JetBrains/kotlin/blob/25a631a1ca8d78f192f4b1a5db2a58d9e886b9b2/compiler/frontend/src/org/jetbrains/kotlin/checkers/diagnostics/TextDiagnostic.kt#L120

shaeberling commented 3 years ago

Hi, I think I hit another instance of this bug, see: https://github.com/shaeberling/euler/blob/master/kotlin/src/com/s13g/aoc/aoc2020/Day19.kt

Anything i can do to help with this?

xjcl commented 3 years ago

@shaeberling That actually seems like a slightly different issue to me ('"' seems to start a double-quoted string, so the parsing is reversed, meaning strings are treated as code and vice versa)

nishtahir commented 3 years ago

Hi, I think I hit another instance of this bug, see: https://github.com/shaeberling/euler/blob/master/kotlin/src/com/s13g/aoc/aoc2020/Day19.kt

Anything i can do to help with this?

It would be awesome to get some help with this. Where you can start would be to take a look here. This is where strings are matched https://github.com/nishtahir/language-kotlin/blob/89d2d5e185e9674bdf4b9e25c50be01842696af7/src/literals.YAML-tmLanguage#L32

For an example of how to write tests for the content, you can check out the example here https://github.com/nishtahir/language-kotlin/blob/89d2d5e185e9674bdf4b9e25c50be01842696af7/test/literals.test.kt#L89

You see how it would look on github, you can use lightshow. Just remember to run a build between changes and use the XML output in the app. I'm happy to help answer more questions if needed.

shaeberling commented 3 years ago

I created a patch that will address my issue (not the original one mentioned in here yet, though I am happy to look into that as well.

I basically used a negative look-ahead regex to ensure there is no single quotation next to the double quotation.

This is the first time I am dealing with tmLanguage, so apologies if this is not the right thing to do. Also one question, since I am new to this: I am surprised that there is no special rule to cover "character" literals in single quotes, like in val foo = 'F'. If this was a thing I guess there was an easier way to have punctuation.definition.character.begin.kotlin which could then be used to avoid starting a string inside a character.

But given that this doesn't seem to exist, I went with the simple negative lookahead, which doesn't break any tests and fixed the issue with my code.

shaeberling commented 3 years ago

Added a fix for the original problem reported here, while I was at it. This should fix it for any number of quotation mark inside a triple quoted string. Uses the same mechanism as with the other patch: Use negative look-ahead to not start closing a triple-quoted string until the last quotation mark in the series.

nishtahir commented 3 years ago

This should be resolved as of #35. Closing

xjcl commented 3 years ago

Awesome! Let's hope GitHub integrates this change soon