4

I am having a problem with using reserved keywords of Java in Kotlin. As not all the reserved keywords are available in Kotlin, Kotlin compiler can not (does not?) detect the reserved keywords that are only in Java.

For example, take the example of default. It is a Java reserved keyword. That means you can not do as follows.

public class UserJava {
    public String default;
}

However, it is NOT a reserved keyword in Kotlin, so you can use it as follows

class UserKotlin {
    var default: String? = null
}

For someone who does not know Java, it would be difficult to know that they are reserved keyword. As Kotlin compiler does not give you an error, or any kind of warning that you are using a reserved keyword, it may cause some problems later, which you would not expect.

One of the problems that it may encounter is during AnnotationProcessing which are the libraries that you include in your gradle with kapt or annotationProcessor. As Kotlin uses Java compiler when you, for example, try to get the fields of UserKotlin class, you would get an empty list as Java compiler does NOT "understand" the field default and ignores it (skips it?).

Real life example would be if you use Room library and have a entity as below

@Entity
class User{
    @PrimaryKey
    var id: Int = 0
    var default: String? = null
}

Room annotation processor will generate an SQLite create query of

CREATE TABLE IF NOT EXISTS `User` (`id` INTEGER NOT NULL, PRIMARY KEY(`id`))

So, it basically skipped the default field.

Is there any way that Kotlin gives warning when I try to use Java reserved keywords? Or is a bug in Kotlin which is yet to be fixed? Or is there any documentation that mentioned this problem.

If I know Java, then I might be relucted to use such keywords as I know that these are reserved in Java. But what if I don't know Java and can't figure out what the problem is?

musooff
  • 6,412
  • 3
  • 36
  • 65
  • It's a bug in the annotation processor you're using, not in Kotlin. For Kotlin, reserved keywords of Java or any other language have no special meaning. – yole Jan 10 '19 at 11:28
  • @yole it may be Annotation Processing Tool bug, but not annotation processor. That's because of `ElementFilter.fieldsIn(entity.getEnclosedElements())` gives only `id` if entity is `User` class. – musooff Jan 11 '19 at 10:58
  • @yole for a reference take a look at this [project](https://github.com/musooff/room/tree/master/roomextension) – musooff Jan 11 '19 at 11:00

2 Answers2

2

I honestly doubt this is a problem within the JVM, but with the annotation library. Kotlin doesn't expose the default variable; what is public/exposed are the getter and the setter. That said, maybe the annotation library is trying to access the private field directly and ends up not finding it because it is a reserved keyword and kotlin compiler may have given it a different name. Isn't the library giving any warning at all on runtime?

That said, kotlin is planning to spread over javascript/native, and with jvm becoming just part of its empire I don't think they have any plans to add your suggested warnings. I guess the libraries will have to adapt to that or lose adepts over time.

1

Android Lint has an optional "No Hard Kotlin Keywords" rule already that warns when using Kotlin keywords in Java code as identifiers, and their interop guide also warns not to use these keywords in Java code.

The same could probably be easily implemented the other way around as an inspection in the Kotlin plugin itself, ideally off by default because most people won't need it, but it would still be useful in some cases. I haven't found an issue for this on YouTrack yet, but I think it would be reasonable to open one.

zsmb13
  • 85,752
  • 11
  • 221
  • 226