M8 is out!

It’s been a really busy couple of months since the last release and we’ve been working hard on making substantial improvements, particularly in terms of speed. We have a lot of goodies for this release. Let’s get started

JVM

Reflection for properties

As a first peek into the future reflective capabilities of Kotlin, you can now access properties as first-class objects in Kotlin:

The “::propertyName” syntax gives a property object so you can get or set its value. You can also access the name of the property (will be useful for frameworks of all sorts). We will add more capabilities in the future.

To access a property that is a member of a class, you can say

And, of course, it works for extensions as well:

Another side of Kotlin’s reflection is its interoperability with Java’s reflection. For example, to find a backing field or a Java method that serves as a getter for a Kotlin property, you can say something like this:

We will develop reflection capabilities further in the next few months. The ultimate goal is to provide framework writers with really powerful tools for their needs. Things on the agenda include proper Kotlin class introspection, making types available through reflection, bringing reflection capabilities to callable references (::functionName) and more. Stay tuned.

Inline Function Improvements

Some enhances for inlining functions including:

  • Support for functions with default parameters.
  • Inlines into objects are supported.

To demonstrate these two features together, let’s look at the following example. Say, we have an Value interface:

Now, let’s say we want to create values whose computations are guarded by a lock:

Our guardedValue() is an inline function. Now, the lock parameter has a default value (a new ReentrantLock is created for every value). Then, the object expression inside this function “captures” the compute parameter, and inlines it directly inside the anonymous class created. This results in only one class and one object emitted (and stored) per value, instead of two classes and two objects for the non-inline case.

Reporting platform signature clashes

The compiler now emits errors when some JVM signatures it generates are going to clash in the byte code (previously this could lead to ClassFormatError’s or to accidentally overriding a superclass’ method without knowing it).

For example, the following Kotlin code looks harmless, but breaks on the JVM:

Now, Kotlin complains about this code:

The reason is that the getter for x has the same name (getX) and signature (takes no parameters, returns Int) as the function declared next to it and JVM does not allow such things in class files.

Another case is an accidental override:

Here, the getter for x again has the same signature as getX(), but they are now in different classes, so the getter would silently override the function, so that Derived(2).getX() would return 2 instead of 1.

Now the compiler catches this and the error is

One may wonder why wouldn’t we, say, rename one of the functions automatically instead of emitting an error? The answers lie in the realm of Java interoperability (nobody likes names invented by the compiler) and binary compatibility (names of things must never change silently, or all dependent code will unexpectedly break). On the other hand, you can specify desired JVM names manually with the platformName annotation:

Note that nothing changes when for the Kotlin clients of this code, but Java clients must use the platform name (doGetX) instead of Kotlin name (getX).

WARNING: This is a breaking change, some of your existing code may need to be fixed.

Support for transient, synchronized and strictfp

In addition to the long-available volatile. We now support transient, synchronized and strictfp as annotations. The semantics are exactly like in Java:

Generated code speedup

  • Generated code for delegated properties works much faster now, and make a lot fewer memory allocations.
  • In addition when statements with constants are faster because of dedicated bytecode instructions now being used.

JavaScript Support

  • You now have Data Classes support in JavaScript. This means that you can now get toStringequals and hashCode generated automatically when annotating classes with the data annotation in JavaScript too, as well as in Java.
  • In addition, LinkedHashSet and LinkedHashMap are also supported in JavaScript.

Language Changes

A few language changes, all of which are breaking changes, so important to take note:

  • private in a package now means private to the current package inside the module. Packages with the same name in other modules won’t see these definitions. Note that packages are nested, so privates are also visible to subpackages in the same module.
  • Extension Properties cannot have backing fields. This was never recommended anyway.
  • If you ever discovered that Kotlin allowed “@” and “@@” as label names, we are sorry to tell you that this is no longer so.

Additions to Standard Library

The standard library gets some new functionality also:

  • slice() function added that takes an iterable of integers and returns a list containing the elements in said positions.
  • join() works on iterables (array, lists, etc.) of strings and combines them into one string
  • joinToString() works on iterables or arrays of any type and is equivalent to .map { it.toString() }.join()
  • Maps now have overloaded functions contains()., thus enabling things like “key in map” by convention
  • Strings now can take advantage of collection like functions including
      • substringBefore, substringBeforeLast and substringAfter, substringAfterLast allowing to find string before and after a certain character or string.
      • replaceBefore, replaceBeforeLast and replaceAfter, replaceAfterLast allowing to replace strings before and after a certain character or string.
      • appendln added to StringBuilder
      • A new StringBuilder function that takes a String builder extensions, allowing for code such as:

  • Iterables now have merge function which returns a new list containing elements merged from two collections on which a transformation has been applied

    This is different to zip in that merge would be:

    and zip would be:

  •  Support for set operations such as union, intersect and substract 

See API docs for more details.

IntelliJ IDEA 14 EAP support and more

In addition to supporting the recently opened IntelliJ IDEA 14 EAP, we have a lot of new IDE features:

Debugger Improvements

  • Ability to do Smart Step Into
  • Evaluate Expression is now supported

New Refactorings

  • Move Top Level Declarations to a new fileMove Function
  • Extract Function. Still needs some improvements, but works in many cases.
  • Extract Local Function.

New Intentions

We love intentions. We believe that they not only quickly help you solve problems, but also teach you and help you discover language and framework constructs. With this release we’ve added 14 new intentions, including:

  • DeMorgan’s Law
    DeMorgans Law
  • Flip binary expression
  • Split if conditionals
  • Replace with operator sign
  • Replace with traditional assignment
  • Replace with infix call
    Infix
  • Simplify boolean expressions
  • Add/Remove explicit type arguments
  • Convert assert to if with throw and viceversa
  • Convert if to ?: and viceversa
  • Convert !! to if and viceversa
  • Make types explicit/implicit in lambdas
  • Convert forEach { } to a for loop and viceversa
  • Convert String concatenation to interpolation and viceversa
    String Interpolation

Smart Completion Improvements

More improvements when it comes to Smart Completion with support for:

  • Smarter completion on overloaded methods.
  • Callable references now show up in smart completion, meaning you can get completion for ::functionNames.
  • Completion in Lambdas.
  • !! and ?: for nullable members
  • Completion in Anonymous classes (object expressions)
  • Completion for constants in when() statements

Other IDE Improvements

In addition to the above, we’ve also:

  • Improved Formatter
  • Structure View now shows members of supertypes
  • Speedups in highlighting and completion
  • Java to Kotlin Converter improved

Finally, we now also support the latest versions of Gradle and Android Studio (0.10, 0.11 and 0.12).

Download the latest release and as always, feedback welcome! IntelliJ EAP 14 already includes the latest plugin, and as always you can find the plugin on our plugin repository.

 

 

This entry was posted in General and tagged . Bookmark the permalink.

24 Responses to M8 is out!

  1. Maarten says:

    At first glance, it looks like the comments on the last example in the Reflection section (with javaField and javaGetter) are swapped around. I’d expect A.p for the field and A.getP() for the getter.

  2. RyotaMurohoshi says:

    Sorry. This question may be off topic.
    Are there any documents about access modifiers?
    I can’t find it.

    I want to know and check access modifier for package function.
    Are there any document about that?
    Sorry if there is the document.

    I found this thread.
    http://devnet.jetbrains.com/thread/451236?tstart=0

    But I want public document about access modifier.

    > private in a package now means private to the current package inside the module. Packages with the same name in other modules won’t see these definitions. Note that packages are nested, so privates are also visible to subpackages in the same module.

  3. Guangyu HE says:

    Can I use Kotlin-plugin 0.8.11 with IdEA 13.1.3?

  4. curtis says:

    Given how good Android L looks, Java hating dev’s will be looking for ‘the’ alt-Java for Android? Kotlin given the Jetbrains Android Studio association is in a good position vs Scala, xTend, Groovy etc.

    Also, eventually I think Google will have to do a Swift because:
    1. Java is too damn verbose and tedious.
    2. Oracle. Maybe even complie directly to dalvik to avoid Java associations.

    Is Android a primary focus going forward for Kotlin.

  5. Bo Hu says:

    How about a central repository of annotation files for Java libraries?

    The built-in null safe system of Kotlin makes working with Java libraries a bit inconvenient:
    1. Although Kannotator does a decent job to generate annotations from byte code, I still have to manually add or change some of them.

    2. Annotation files also affect compiler’s behavior. The same Kotlin code files that access Java libraries may not be compilable with different annotation files.

  6. Guangyu HE says:

    On Reflection, I have wrotten:

    class Hello(val x:Int, val y:Int)

    fun testReflection() {
    val h = Hello(3,4) // I don’t like it
    javaClass().getDeclaredFields().forEach {
    val name = it.getName()!!
    if (!name.startsWith(‘$’)) {
    Log.v(it.getName()!!)
    it.setAccessible( true )
    it.set(h,2)
    }
    }
    system.out.println(“${h.x}, ${h.y}”)
    }

    I want to initialize Hello instance by reflection only, so I hate to write the following code:
    val h = Hello(3,4) // initialization. It’s not the way I hope.

    Is there a better way to implement it ?

  7. Daniel Alves says:

    I’ve ported some parts of my website’s functionality from Typescript to Kotlin. I’m working with angular, and for the most of the time, I’m very happy with the changes in language and in the IDE. But I miss the ability to grab the type (function) of a class in javascript (the javaClass does not work). I had to create some workarounds to work. So, maybe the js compiler could have this feature! ;)

    Only one more thing, I think that if the javaClass keyword may be changed to typeOf or classOf to better fit in the target end, just because kotlin does not only have java classes, it has javascript classes as well, and maybe .net classes in future! ;)

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">