Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Kotlin DSL in under an hour

Kotlin DSL in under an hour

Learn how to create your own DSL in Kotlin

Anton Arhipov

October 18, 2018
Tweet

More Decks by Anton Arhipov

Other Decks in Programming

Transcript

  1. createHTML().html { head { +"Hello!" } body { ul {

    p { +"This is my awesome text!" } } } } kotlinx.html https://github.com/Kotlin/kotlinx.html
  2. Anko https://github.com/Kotlin/anko verticalLayout { padding = dip(30) val name =

    editText { hint = "Name" textSize = 24f } val pwd = editText { hint = "Password" textSize = 24f button("Login") { textSize = 26f onClick { toast("Hello, ${name.text}!") } }
  3. Gradle Kotlin DSL https://github.com/gradle/kotlin-dsl plugins { java kotlin("jvm") version "1.2.70"

    } group = "org.arhan" version = "1.0-SNAPSHOT" repositories { maven { setUrl("http://dl.bintray.com/kotlin/kotlin-eap") } jcenter() } dependencies { val kotlinx_html_version = "0.6.11" compile(kotlin("stdlib-jdk8")) compile("org.jetbrains.kotlinx:kotlinx-html-jvm:${kotlinx_html_version}") testCompile("junit", "junit", "4.12")
  4. Exposed https://github.com/JetBrains/Exposed object Cities : Table() { val id =

    integer("id").autoIncrement().primaryKey() // Column<Int> val name = varchar("name", 50) // Column<String> } transaction { create (Cities) val tallinnId = Cities.insert { it[name] = "Tallinn" } get Cities.id for (city in Cities.selectAll()) { println("${city[Cities.id]}: ${city[Cities.name]}") } }
  5. https://github.com/nfrankel/kaadin Kaadin theme = "valo" verticalLayout(margin = true, spacing =

    true) { tabSheet { tab("Interactions") { accordion { tab("Button", HAND_O_RIGHT) { horizontalLayout(true, true) { button() button("Label") button("Label", HAND_O_RIGHT) button("Click me", onClick = { show("Clicked") }) button("Click me", HAND_O_RIGHT, { show("Clicked") }) } }
  6. Kotlin DSL in TeamCity project { vcsRoot(ApplicationVcs) buildType { id("Application")

    name = "Application" vcs { root(ApplicationVcs) } artifactRules = "target/*jar" steps { maven { goals = "clean package" } } triggers { vcs {} } dependencies { snapshot(Library) {}
  7. fun main(args: Array<String>) { embeddedServer(Jetty, commandLineEnvironment(args)).start(wait = true) } fun

    Application.main() { install(DefaultHeaders) install(CallLogging) routing { get("/") { call.respondHtml { head { title { +"Ktor App" } } body { p { +"Hello from Ktor!" } } Ktor
  8. foo { bar { baz = "Hello!" qux = quux

    { corge = "Blah" } } }
  9. foo { bar { baz = "Hello!" qux = quux

    { corge = "Blah" } } }
  10. foo { bar { baz = "Hello!" qux = quux

    { corge = "Blah" } } }
  11. foo { bar { baz = "Hello!" qux = quux

    { corge = "Blah" } } }
  12. foo { bar(grault = 1) { baz = "Hello!" qux

    = quux { corge = "Blah" } } }
  13. foo { bar(grault = 1) { baz = "Hello!" qux

    = quux { corge = Blah() } } }
  14. foo { bar(grault = 1) { baz = "Hello!" qux

    = quux { corge = Blah() } } }
  15. final ClientBuilder builder = new ClientBuilder(); builder.setFirstName("Anton"); builder.setLastName("Arhipov"); final TwitterBuilder

    twitterBuilder = new TwitterBuilder(); twitterBuilder.setHandle("@antonarhipov"); builder.setTwitter(twitterBuilder.build()); final CompanyBuilder companyBuilder = new CompanyBuilder(); companyBuilder.setName("JetBrains"); companyBuilder.setCity("Tallinn"); builder.setCompany(companyBuilder.build()); final Client client = builder.build(); System.out.println("Created client is: " + client); val client = createClient { firstName = "Anton" lastName = "Arhipov" twitter { handle = "@antonarhipov" } company { name = "JetBrains" city = "Tallinn" } } println("Created client is: " + client.consoleString)
  16. //extension property val Client.consoleString: String get() = "${twitter.handle} ${company.name}" //extension

    method fun Client.toConsoleString(): String { return "${twitter.handle} ${company.name}" }
  17. fun createClient(c: ClientBuilder.() -> Unit): Client { val builder =

    ClientBuilder() c(builder) return builder.build() } fun ClientBuilder.company(t: CompanyBuilder.() -> Unit) { company = CompanyBuilder().apply(t).build() } fun ClientBuilder.twitter(t: CompanyBuilder.() -> Unit) { twitter = TwitterBuilder().apply(t).build() } Lambda with receiver Extension methods
  18. twitter { handle = "@antonarhipov" company { name = "JetBrains"

    city = "Tallinn" } } @DslMarker annotation class ClientDsl @ClientDsl class CompanyBuilderDsl : CompanyBuilder() @ClientDsl class TwitterBuilderDsl : TwitterBuilder() twitter { handle = "@antonarhipov" company { name = "JetBrains" city = "Tallinn" } } Scope control
  19. dateTime = LocalDateTime.of(2018, Month.DECEMBER, 11, 0, 0) dateTime = 11

    December 2018 at (14 hh 0) infix fun Int.December(n: Int) : LocalDate { return LocalDate.of(n, Month.DECEMBER, this) } infix fun LocalDate.at(n: Pair<Int, Int>): LocalDateTime { return this.atTime(n.first, n.second) } infix fun Int.hh(n: Int): Pair<Int, Int> { return Pair(this, n) }
  20. me { name = "Anton Arhipov" twitter = "@antonarhipov" }

    books { courses { Kotlin { Try = "try.kotlinlang.org" Slack = "slack.kotl.in" }