Skip to content

Commit

Permalink
Add installation guide
Browse files Browse the repository at this point in the history
  • Loading branch information
Him188 committed Jul 12, 2020
1 parent 1284f0f commit c983e4f
Show file tree
Hide file tree
Showing 18 changed files with 224 additions and 52 deletions.
34 changes: 34 additions & 0 deletions README-chs.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,37 @@ fun test(a1: Int, a2: Any): String = runBlocking { test(a1, a2) }
## 现在体验

基于编译器 IR 后端的代码生成已经完成, 可启用 IR 后端后添加 Gradle 插件依赖:

1. 第一步: 安装 Gradle 插件.

`build.gradle``build.gradle.kts`
```kotlin
plugins {
id("net.mamoe.kotlin-jvm-blocking-bridge") version "0.1.12"
}
```

如果 Gradle 无法下载这个插件, 请在 `settings.gradle``settings.gradle.kts` 中添加 `gradlePluginPortal()`:
```kotlin
pluginManagement {
repositories {
gradlePluginPortal()
}
}
```

本插件会自动添加如下的依赖:
```kotlin
implementation("net.mamoe:kotlin-jvm-blocking-bridge")
```
因此只需要安装插件, 而不需要添加依赖即可使用

2. 第二步, 使用 IR 后端.

添加下面内容到 `build.gradle``build.gradle.kts`
```kotlin
```kotlin
tasks.withType<KotlinCompile> {
kotlinOptions.useIR = true
}
```
33 changes: 30 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,38 @@ TODOs:

## Try now

You can try it now with Kotlin Compiler IR backend:
You can try it now with Kotlin Compiler IR backend.

1. First step: Install Gradle plugin.

`build.gradle` or `build.gradle.kts`
```kotlin
plugins {
id("net.mamoe.kotlin-jvm-blocking-bridge") version "0.1.3"
id("net.mamoe.kotlin-jvm-blocking-bridge") version "0.1.12"
}
```

If gradle can't resolve plugin, please add `gradlePluginPortal()` into `settings.gradle` or `settings.gradle.kts`:
```kotlin
pluginManagement {
repositories {
gradlePluginPortal()
}
}
```
```

The plugin will automatically install runtime annotation library for you, as:
```kotlin
implementation("net.mamoe:kotlin-jvm-blocking-bridge")
```
Therefore, you need only to install the plugin.

2. Second step, use IR backend.

Add this into `build.gradle` or `build.gradle.kts`
```kotlin
```kotlin
tasks.withType<KotlinCompile> {
kotlinOptions.useIR = true
}
```
2 changes: 1 addition & 1 deletion buildSrc/src/main/kotlin/Versions.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
object Versions {
const val project = "0.1.3"
const val project = "0.1.12"

const val kotlin = "1.4-M3"
const val coroutines = "1.3.7"
Expand Down
6 changes: 4 additions & 2 deletions compiler-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ dependencies {

compileOnly("org.jetbrains.kotlin:kotlin-compiler-embeddable:${Versions.kotlin}")

kapt("com.google.auto.service:auto-service:1.0-rc6")
compileOnly("com.google.auto.service:auto-service-annotations:1.0-rc6")
kapt("com.google.auto.service:auto-service:1.0-rc7")
compileOnly("com.google.auto.service:auto-service-annotations:1.0-rc7")

testImplementation(kotlin("reflect"))

testImplementation("org.jetbrains.kotlin:kotlin-compiler-embeddable:${Versions.kotlin}")
testImplementation("com.github.tschuchortdev:kotlin-compile-testing:1.2.6")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,32 @@ import org.jetbrains.kotlin.compiler.plugin.AbstractCliOption
import org.jetbrains.kotlin.compiler.plugin.CliOption
import org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.CompilerConfigurationKey

class JvmBlockingBridgeCommandLineProcessor : CommandLineProcessor {
override val pluginId: String = "net.mamoe.kotlin-jvm-blocking-bridge"
internal val KEY_ENABLED = CompilerConfigurationKey<Boolean>("enabled")

open class JvmBlockingBridgeCommandLineProcessor : CommandLineProcessor {
companion object {
const val PLUGIN_ID = "net.mamoe.kotlin-jvm-blocking-bridge-gradle"
}

override val pluginId: String = PLUGIN_ID

override val pluginOptions: Collection<CliOption> = listOf(
CliOption(
optionName = "blocking-bridge",
valueDescription = "'true' to enable @JvmBlockingBridge annotation",
description = "@JvmBlockingBridge",
required = false,
allowMultipleOccurrences = false
)
)

override fun processOption(
option: AbstractCliOption,
value: String,
configuration: CompilerConfiguration
) {

configuration.put(KEY_ENABLED, value.toBoolean())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,16 @@ import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
import org.jetbrains.kotlin.config.CompilerConfiguration

@Suppress("unused")
class JvmBlockingBridgeComponentRegistrar : ComponentRegistrar {
open class JvmBlockingBridgeComponentRegistrar : ComponentRegistrar {

override fun registerProjectComponents(
project: MockProject,
configuration: CompilerConfiguration
) {
if (configuration[KEY_ENABLED] == false) {
return
}

IrGenerationExtension.registerExtension(project, JvmBlockingBridgeIrGenerationExtension())
ExpressionCodegenExtension.registerExtension(project, JvmBlockingBridgeCodegenJvmExtension())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ class JvmBlockingBridgeIrGenerationExtension : IrGenerationExtension {
}

internal fun ClassLoweringPass.runOnFileInOrder(irFile: IrFile) {
irFile.acceptChildrenVoid(object : IrElementVisitorVoid {
irFile.acceptVoid(object : IrElementVisitorVoid {
override fun visitElement(element: IrElement) {
element.acceptVoid(this)
element.acceptChildrenVoid(this)
}

override fun visitClass(declaration: IrClass) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package net.mamoe.kjbb.jvm

import org.jetbrains.kotlin.codegen.ImplementationBodyCodegen
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
Expand All @@ -27,6 +28,8 @@ class BridgeCodegen(
}

fun SimpleFunctionDescriptor.generateBridge() {
val originalFunction = this

println("generating bridge: ${this.valueParameters}, ${this.isSuspend}")
val desc = AnonymousFunctionDescriptor.create(
clazz,
Expand All @@ -38,11 +41,11 @@ class BridgeCodegen(
initialize(
null,
ReceiverParameterDescriptorImpl(clazz, clazz.thisAsReceiverParameter.value, Annotations.EMPTY),
typeParameters,
valueParameters.map { it.copy(this, it.name, it.index) },
returnType,
null,
visibility
originalFunction.typeParameters,
originalFunction.valueParameters.map { it.copy(this, it.name, it.index) },
originalFunction.returnType,
Modality.FINAL,
originalFunction.visibility
)

isSuspend = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension
*/
open class JvmBlockingBridgeCodegenJvmExtension : ExpressionCodegenExtension {
override fun generateClassSyntheticParts(codegen: ImplementationBodyCodegen) {
return
BridgeCodegen(codegen).generate()
}

Expand Down
21 changes: 21 additions & 0 deletions compiler-plugin/src/test/kotlin/TestComponentRegistrar.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import net.mamoe.kjbb.ir.JvmBlockingBridgeIrGenerationExtension
import net.mamoe.kjbb.jvm.JvmBlockingBridgeCodegenJvmExtension
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension
import org.jetbrains.kotlin.com.intellij.mock.MockProject
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
import org.jetbrains.kotlin.config.CompilerConfiguration

@Suppress("unused")
open class TestComponentRegistrar : ComponentRegistrar {

override fun registerProjectComponents(
project: MockProject,
configuration: CompilerConfiguration
) {
IrGenerationExtension.registerExtension(project, JvmBlockingBridgeIrGenerationExtension())
ExpressionCodegenExtension.registerExtension(project, JvmBlockingBridgeCodegenJvmExtension())
}
}


Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
@file:Suppress("UNCHECKED_CAST", "RemoveRedundantBackticks")

package ir


import compile
import org.intellij.lang.annotations.Language
import org.junit.jupiter.api.Test
import kotlin.test.assertEquals
Expand All @@ -9,7 +12,7 @@ fun testTestData(
@Language("kt")
source: String
) {
val result = compile(source)
val result = compile(source, true)

@Suppress("UNCHECKED_CAST")
val test = result.classLoader.loadClass("TestData")
Expand All @@ -21,7 +24,7 @@ fun testTestData(
}

@Suppress("RedundantSuspendModifier")
class TestCompiling {
class TestCompilerInIrBackend {

@Test
fun `no param, no extension receiver`() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
import org.intellij.lang.annotations.Language
package ir

import org.junit.jupiter.api.Test
import kotlin.test.assertFails

private fun test(
@Language("kt")
source: String
) {
val result = compile(source)

val testData = result.classLoader.loadClass("TestData")
}

internal class TestForInterface {

@Test
Expand Down
18 changes: 18 additions & 0 deletions compiler-plugin/src/test/kotlin/jvm/TestCompilerInJvmBackend.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package jvm

internal class TestCompilerInJvmBackend {

//@Test
fun `simple function in object`() = testJvmCompile(
"""
object TestData {
@JvmBlockingBridge
suspend fun test(): String{
return "OK"
}
fun main(): String = this.runFunction("test")
}
"""
)
}
20 changes: 20 additions & 0 deletions compiler-plugin/src/test/kotlin/jvm/testJvmCompile.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package jvm

import compile
import org.intellij.lang.annotations.Language
import kotlin.test.assertEquals

fun testJvmCompile(
@Language("kt")
source: String
) {
val result = compile(source, false)

@Suppress("UNCHECKED_CAST")
val test = result.classLoader.loadClass("TestData")
assertEquals(
"OK",
(test.kotlin.objectInstance!!).run {
this::class.java.methods.first { it.name == "main" }.invoke(this)
} as String)
}
8 changes: 4 additions & 4 deletions compiler-plugin/src/test/kotlin/util.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.tschuchort.compiletesting.KotlinCompilation
import com.tschuchort.compiletesting.SourceFile
import net.mamoe.kjbb.JvmBlockingBridgeComponentRegistrar
import org.intellij.lang.annotations.Language
import java.io.File
import java.lang.reflect.Modifier
Expand All @@ -22,7 +21,8 @@ fun <R> Class<*>.runStaticFunction(name: String, vararg args: Any): R {

fun compile(
@Language("kt")
source: String
source: String,
ir: Boolean
): KotlinCompilation.Result {
val kotlinSource = SourceFile.kotlin(
"TestData.kt", "import kotlin.test.assertEquals\n$source"
Expand All @@ -31,12 +31,12 @@ fun compile(
return KotlinCompilation().apply {
sources = listOf(kotlinSource)

compilerPlugins = listOf(JvmBlockingBridgeComponentRegistrar())
compilerPlugins = listOf(TestComponentRegistrar())
verbose = false

workingDir = File("testCompileOutput").apply { mkdir() }

useIR = true
useIR = ir

inheritClassPath = true
messageOutputStream = System.out
Expand Down
15 changes: 8 additions & 7 deletions gradle-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar

plugins {
kotlin("jvm")
kotlin("kapt")
Expand All @@ -10,14 +8,15 @@ plugins {
`maven-publish`
id("com.jfrog.bintray")

id("com.github.johnrengelman.shadow")
// id("com.github.johnrengelman.shadow")
}

dependencies {
implementation(kotlin("stdlib"))
compileOnly(kotlin("stdlib"))
compileOnly(gradleApi())
implementation(kotlin("gradle-plugin-api"))

compileOnly(kotlin("gradle-plugin-api"))
compileOnly(kotlin("gradle-plugin"))
implementation("io.github.classgraph:classgraph:4.8.47")
compileOnly("org.jetbrains.kotlin:kotlin-compiler-embeddable:${Versions.kotlin}")

api(project(":kotlin-jvm-blocking-bridge-compiler"))
Expand Down Expand Up @@ -45,8 +44,10 @@ gradlePlugin {
}
}

/*
tasks.getByName("shadowJar", ShadowJar::class) {
archiveClassifier.set("")
}
tasks.publishPlugins.get().dependsOn(tasks.shadowJar.get())
tasks.publishPlugins.get().dependsOn(tasks.shadowJar.get())
*/
Loading

0 comments on commit c983e4f

Please sign in to comment.