tree: aeffcf31f2af5aa22a5ad783656e6f3060dd47ca [path history] [tgz]
  1. compiler-plugin/
  2. compiler-plugin-embeddable/
  3. runtime/
  4. README.md
plugins/js-plain-objects/README.md

JavaScript Plain Objects compiler plugin

This directory contains the runtime and the compiler plugin of the js-plain-objects plugin. The Gradle and Maven plugins are located in the libraries/tools directory.

:warning: The js-plain-objects compiler plugin only works with the K2 compiler.

Plugin overview

The js-plain-objects plugin helps you to create type-safe plain JavaScript objects. To create a plain JavaScript object, declare an external interface and annotate it with @JsPlainObject. For example:

@JsPlainObject
external interface User {
    val name: String
    val age: Int
    val email: String?
}

The plugin adds a few extra declarations to create and copy the object with such a structure easily:

@JsPlainObject
external interface User {
    val name: String
    val age: Int
    val email: String?
}

// Created by the plugin declarations
inline operator fun User.Companion.invoke(name: String, age: Int, email: String? = NOTHING): User =
    js("({ name: name, age: age, email: email })")

inline fun User.copy(name: String = NOTHING, age: Int = NOTHING, email: String? = NOTHING): User =
    js("Object.assign({}, this, { name: name, age: age, email: email })")

To create an object with the defined structure, call User as a constructor:

fun main() {
    val user = User(name = "Name", age = 10)
    val copy = user.copy(age = 11, email = "some@user.com")

    println(JSON.stringify(user)) 
    // { "name": "Name", "age": 10 }
    println(JSON.stringify(copy)) 
    // { "name": "Name", "age": 11, "email": "some@user.com" }
}

The Kotlin code will be compiled into the following JavaScript code:

function main() {
    var user = { name: "Name", age: 10 };
    var copy = Object.assign({}, user, { age: 11, email: "some@user.com" });

    println(JSON.stringify(user));
    // { "name": "Name", "age": 10 }
    println(JSON.stringify(copy));
    // { "name": "Name", "age": 11, "email": "some@user.com" }
}

Any JavaScript objects created with this approach are safer because you will have a compile-time error if you use the wrong property name or value type.

Plugin structure

The plugin consists of the following parts:

  1. backend — responsible for IR code generation.
  2. k2 — code resolution and diagnostics for the new K2 Kotlin compiler.
  3. cli — extension points that allow the plugin to be loaded with -Xplugin Kotlin CLI compiler argument.
  4. common — common declarations for other parts.

Tests and test data are common for all parts and located directly in this module. (See testData and tests-gen folders).

Building and contributing

Prerequisites

Before you begin, it is recommended to read the root README.md file and ensure that you have all the necessary tools installed.

Note: You don't need JDK6 installed to work with this plugin.

Install locally

Run ./gradlew dist install to get a fresh version of the Kotlin compiler and the js-plain-objects plugin in your Maven local directory with the latest 2.x.255-SNAPSHOT versions.

Work with tests

Like most Kotlin project modules, tests are generated based on test data. Tests are located in the test-gen folder and can be run using the green arrow in the IDE gutter or with the standard ./gradlew :plugins:js-plain-objects:compiler-plugin:test task. To add a new test, add an appropriate file to the testData folder and then re-generate tests with ./gradlew :plugins:js-plain-objects:compiler-plugin:generateTests.

Contribute

Follow Kotlin's contribution guidelines. If you want to report an issue, request a feature or ask for help, create an issue in our issue tracker.