Movatterモバイル変換


[0]ホーム

URL:


Skip to contentBurger menu icon
Kotlin logo

Kotlin

A concise multiplatform language developed by JetBrains

Language design

Upcoming Change: Syntax For Annotations

Kotlin’s syntax for annotations was inspired by C#, which surrounds them with square brackets:

[Inject]fun setFoo(foo: Foo) { ... }

But brackets are precious for a language designer, and we would really like to use them later for something else, so we are considering changing the annotation syntax to the more Java-like@-based one:

@Injectfun setFoo(foo: Foo) { ... }

NOTE: the short syntax that does not require[...] nor@ is going to be kept anyways, so you will still be able to say this:

data class Foovolatile var bar: Bar = ...

This change has some implications, though.

Labels

First of all, the@-syntax is already in use, for labels:

@loopfor (i in 1..20) {    if (enough(i)) break@loop    println(i)}

Since expressions can be annotated as well as declarations, we need to change something here. The simplest option would be to move the@ to the end of a label declaration:

loop@for (i in 1..20) {    if (enough(i)) break@loop    println(i)}

Note that the use site (break@loop) is not changed, and still looks pretty nice :)

Targeting

We are also looking into how we could prescribe what an annotation should be attached to in the generated.class-file:

class C(@Ann("arg") var foo: Int)

We have quite a few options here: the@Ann annotation can be put on

  • the field wherefoo is stored
  • the propertyfoo itself (not a Java declaration)
  • getter offoo
  • setter offoo
  • parameterfoo of the primary constructor ofC

Some annotations are only applicable to, say, fields, and for those there’s no question, but some allow many possible targets. To express the intent, some additional syntax is needed.

One option would be to prefix the annotation type name with the target(s):

class C(@field:Ann("arg") var foo: Int)

(many targets can be separated by a comma)

Another option would be to do what Scala does:

class C(@(Ann@field)("arg") var foo: Int)
  • Downside: too many parentheses
  • Upside:@field is also an annotation (yes,Ann is anannotated annotation), which means more extensible syntax and fewer concepts in the language

Yet another option would be to have@field annotation whose arguments are annotations for the field:

class C(@field(@Ann("arg")) var foo: Int)
  • Upside: even fewer language changes than the previous case
  • Downside: if the same annotation goes to two targets (e.g. getter and setter), it has to be duplicated

A modification of this approach:

class C(@at(FIELD, @Ann1("arg"), @Ann2) var foo: Int)class C(@atMany(array(FIELD, PROPERTY), @Ann1("arg"), @Ann2) var foo: Int)

Then definitions are as follows:

annotation class at(val target: AnnotationTarget, vararg val annotations: Annotation)annotation class atMany(val target: Array<AnnotationTarget>, vararg val annotations: Annotation)

And, for completeness, yet another approach involves adding an explicit (optional) syntax for declaring fields (inside properties):

@Ann1("arg") @Ann2val foo: Int = 1    @Ann1("arg") @Ann2    field _foo    @GetterAnnotation    get
  • Downside: There’s no way to mitigate duplication here
  • Downside: It is likely to become an obscure piece of syntax (like$backingField) which is used rarely and supported poorly by tools

Annotations on Local Declarations

Our users seem to often write something like this:

fun example() {    data class Example(val foo: String, val bar: Int) // Error on this line    ...}

This does not parse correctly, becausedata is not a keyword (neither isopen, btw), so we need to write it like this:

fun example() {    @data class Example(val foo: String, val bar: Int) // OK    ...}

Now, what if I want anopen local class, orabstract? Those aremodifiers, not annotations, and we can’t say@open or@abstract.

One option is to allow escaping modifiers with@ as well as annotations:

fun example() {    @open class Example(val foo: String, val bar: Int)    ...}

Other options include allowing modifierson the same line with the class, but this does not straightforwardly extend to functions, which areexpressions now. See morehere

Feedback Welcome

What do you think?

P.S. BTW, we are working on a spec document drafthere

Prev post Upcoming Feature DeprecationsMore Deprecations ComingNext post

Subscribe to Kotlin Blog updates

By submitting this form, I agree that JetBrains s.r.o. ("JetBrains") may use my name, email address, and location data to send me newsletters, including commercial communications, and to process my personal data for this purpose. I agree that JetBrains may process said data usingthird-party services for this purpose in accordance with theJetBrains Privacy Policy. I understand that I can revoke this consent at any time inmy profile. In addition, an unsubscribe link is included in each email.

Thanks, we've got you!

image description

Discover more


[8]ページ先頭

©2009-2025 Movatter.jp