Skip to content

Latest commit

 

History

History

js-plain-objects

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 

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.

⚠️ 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
    @JsExport.Ignore
    companion object {
        inline operator fun invoke(name: String, age: Int, email: String? = NOTHING): User =
            js("({ name: name, age: age, email: email })")

        inline fun copy(source: User, name: String = NOTHING, age: Int = NOTHING, email: String? = NOTHING): User =
            js("Object.assign({}, source, { 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(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" }
}

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.