Merge pull request #26 from bnorm/kotlin-1_4_20
Upgrade to Kotlin 1.4.20
This commit is contained in:
@@ -0,0 +1,9 @@
|
|||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
[*.{kt,kts}]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
@@ -2,27 +2,19 @@ name: Project Build
|
|||||||
|
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
env:
|
||||||
|
GRADLE_OPTS: "-Dorg.gradle.jvmargs=-Xmx4g -Dorg.gradle.daemon=false -Dkotlin.incremental=false"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- uses: gradle/wrapper-validation-action@v1
|
- uses: gradle/wrapper-validation-action@v1
|
||||||
|
- uses: actions/setup-java@v1
|
||||||
- name: Set up JDK 1.8
|
|
||||||
uses: actions/setup-java@v1
|
|
||||||
with:
|
with:
|
||||||
java-version: 1.8
|
java-version: 1.8
|
||||||
|
|
||||||
- uses: actions/cache@v1
|
- run: ./gradlew build
|
||||||
with:
|
- run: cd sample && ./gradlew build browserDistribution || cd ..
|
||||||
path: ~/.gradle/caches
|
|
||||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle.kts') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-gradle-
|
|
||||||
|
|
||||||
- name: Build with Gradle
|
|
||||||
run: ./gradlew build
|
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
name: lint
|
||||||
|
|
||||||
|
on: [pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
ktlint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Run ktlint
|
||||||
|
uses: ScaCap/action-ktlint@1.1
|
||||||
|
with:
|
||||||
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
reporter: github-pr-check
|
||||||
@@ -75,7 +75,7 @@ Builds of the Gradle plugin are available through the
|
|||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm") version "1.4.0"
|
kotlin("jvm") version "1.4.20"
|
||||||
id("com.bnorm.power.kotlin-power-assert") version "0.5.3"
|
id("com.bnorm.power.kotlin-power-assert") version "0.5.3"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -94,7 +94,7 @@ configure<com.bnorm.power.PowerAssertGradleExtension> {
|
|||||||
## Kotlin IR
|
## Kotlin IR
|
||||||
|
|
||||||
Using this compiler plugin only works if the code is compiled using Kotlin
|
Using this compiler plugin only works if the code is compiled using Kotlin
|
||||||
1.4.0 and IR is enabled. This includes all IR based compiler backends: JVM, JS,
|
1.4.20 and IR is enabled. This includes all IR based compiler backends: JVM, JS,
|
||||||
and Native! As Kotlin IR is still experimental, mileage may vary.
|
and Native! As Kotlin IR is still experimental, mileage may vary.
|
||||||
|
|
||||||
##### Kotlin/JVM
|
##### Kotlin/JVM
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm") version "1.4.0" apply false
|
kotlin("jvm") version "1.4.20" apply false
|
||||||
id("org.jetbrains.dokka") version "0.10.0" apply false
|
id("org.jetbrains.dokka") version "0.10.0" apply false
|
||||||
id("com.gradle.plugin-publish") version "0.11.0" apply false
|
id("com.gradle.plugin-publish") version "0.11.0" apply false
|
||||||
id("com.github.gmazzo.buildconfig") version "2.0.2" apply false
|
id("com.github.gmazzo.buildconfig") version "2.0.2" apply false
|
||||||
|
|||||||
@@ -16,13 +16,13 @@
|
|||||||
|
|
||||||
package com.bnorm.power
|
package com.bnorm.power
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
|
import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
|
||||||
import org.jetbrains.kotlin.ir.builders.irConcat
|
import org.jetbrains.kotlin.ir.builders.irConcat
|
||||||
import org.jetbrains.kotlin.ir.builders.irGet
|
import org.jetbrains.kotlin.ir.builders.irGet
|
||||||
import org.jetbrains.kotlin.ir.builders.irString
|
import org.jetbrains.kotlin.ir.builders.irString
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||||
@@ -62,11 +62,10 @@ fun IrBuilderWithScope.buildMessage(
|
|||||||
var row = info.startLineNumber - originalInfo.startLineNumber
|
var row = info.startLineNumber - originalInfo.startLineNumber
|
||||||
|
|
||||||
val columnOffset: Int = when (original) {
|
val columnOffset: Int = when (original) {
|
||||||
is IrMemberAccessExpression -> {
|
is IrMemberAccessExpression<*> -> {
|
||||||
// TODO IrFunction doesn't have 'isInfix' as a property
|
val owner = original.symbol.owner
|
||||||
val descriptor = original.symbol.descriptor
|
|
||||||
when {
|
when {
|
||||||
descriptor is FunctionDescriptor && descriptor.isInfix -> source.indexOf(descriptor.name.asString())
|
owner is IrSimpleFunction && owner.isInfix -> source.indexOf(owner.name.asString())
|
||||||
else -> when (original.origin) {
|
else -> when (original.origin) {
|
||||||
// TODO handle equality and comparison better?
|
// TODO handle equality and comparison better?
|
||||||
IrStatementOrigin.EQEQ, IrStatementOrigin.EQEQEQ -> source.indexOf("==")
|
IrStatementOrigin.EQEQ, IrStatementOrigin.EQEQEQ -> source.indexOf("==")
|
||||||
|
|||||||
+29
-27
@@ -17,6 +17,7 @@
|
|||||||
package com.bnorm.power
|
package com.bnorm.power
|
||||||
|
|
||||||
import com.bnorm.power.internal.ReturnableBlockTransformer
|
import com.bnorm.power.internal.ReturnableBlockTransformer
|
||||||
|
import java.io.File
|
||||||
import org.jetbrains.kotlin.backend.common.*
|
import org.jetbrains.kotlin.backend.common.*
|
||||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
||||||
import org.jetbrains.kotlin.backend.common.ir.asSimpleLambda
|
import org.jetbrains.kotlin.backend.common.ir.asSimpleLambda
|
||||||
@@ -24,7 +25,7 @@ import org.jetbrains.kotlin.backend.common.ir.inline
|
|||||||
import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder
|
import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder
|
||||||
import org.jetbrains.kotlin.backend.common.lower.at
|
import org.jetbrains.kotlin.backend.common.lower.at
|
||||||
import org.jetbrains.kotlin.cli.common.messages.*
|
import org.jetbrains.kotlin.cli.common.messages.*
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
|
import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
|
||||||
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
|
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
|
||||||
@@ -40,7 +41,6 @@ import org.jetbrains.kotlin.ir.declarations.IrFile
|
|||||||
import org.jetbrains.kotlin.ir.declarations.path
|
import org.jetbrains.kotlin.ir.declarations.path
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionExpressionImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionExpressionImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
@@ -48,9 +48,7 @@ import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
|||||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
fun FileLoweringPass.runOnFileInOrder(irFile: IrFile) {
|
fun FileLoweringPass.runOnFileInOrder(irFile: IrFile) {
|
||||||
irFile.acceptVoid(object : IrElementVisitorVoid {
|
irFile.acceptVoid(object : IrElementVisitorVoid {
|
||||||
@@ -75,25 +73,22 @@ class PowerAssertCallTransformer(
|
|||||||
|
|
||||||
override fun lower(irFile: IrFile) {
|
override fun lower(irFile: IrFile) {
|
||||||
file = irFile
|
file = irFile
|
||||||
fileSource = File(irFile.path).readText().replace("\r\n", "\n")
|
fileSource = File(irFile.path).readText()
|
||||||
|
.replace("\r\n", "\n") // https://youtrack.jetbrains.com/issue/KT-41888
|
||||||
|
|
||||||
irFile.transformChildrenVoid()
|
irFile.transformChildrenVoid()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitCall(expression: IrCall): IrExpression {
|
override fun visitCall(expression: IrCall): IrExpression {
|
||||||
// TODO expression.symbol.owner.fqNameSafe includes the wrapping ClassKt while descriptor doesn't
|
val fqName = expression.symbol.owner.kotlinFqName
|
||||||
val fqName = expression.symbol.descriptor.fqNameSafe
|
|
||||||
if (functions.none { fqName == it })
|
if (functions.none { fqName == it })
|
||||||
return super.visitCall(expression)
|
return super.visitCall(expression)
|
||||||
|
|
||||||
// Find a valid delegate function or do not translate
|
// Find a valid delegate function or do not translate
|
||||||
val delegate = findDelegate(fqName) ?: run {
|
val delegate = findDelegate(fqName) ?: run {
|
||||||
val line = fileSource.substring(expression.startOffset).count { it == '\n' } + 1
|
messageCollector.warn(
|
||||||
val location = CompilerMessageLocation.create(file.path, line, -1, null)
|
expression,
|
||||||
messageCollector.report(
|
"Unable to find overload for function $fqName callable as $fqName(Boolean, String) or $fqName(Boolean, () -> String) for power-assert transformation"
|
||||||
CompilerMessageSeverity.WARNING,
|
|
||||||
"Unable to find overload for function $fqName callable as $fqName(Boolean, String) or $fqName(Boolean, () -> String) for power-assertion transformation",
|
|
||||||
location
|
|
||||||
)
|
)
|
||||||
return super.visitCall(expression)
|
return super.visitCall(expression)
|
||||||
}
|
}
|
||||||
@@ -105,13 +100,7 @@ class PowerAssertCallTransformer(
|
|||||||
// If the tree does not contain any children, the expression is not transformable
|
// If the tree does not contain any children, the expression is not transformable
|
||||||
val tree = buildAssertTree(assertionArgument)
|
val tree = buildAssertTree(assertionArgument)
|
||||||
val root = tree.children.singleOrNull() ?: run {
|
val root = tree.children.singleOrNull() ?: run {
|
||||||
val line = fileSource.substring(expression.startOffset).count { it == '\n' } + 1
|
messageCollector.info(expression, "Expression is constant and will not be power-assert transformed")
|
||||||
val location = CompilerMessageLocation.create(file.path, line, -1, null)
|
|
||||||
messageCollector.report(
|
|
||||||
CompilerMessageSeverity.INFO,
|
|
||||||
"Expression is constant and will not be power-assertion transformed",
|
|
||||||
location
|
|
||||||
)
|
|
||||||
return super.visitCall(expression)
|
return super.visitCall(expression)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,7 +141,7 @@ class PowerAssertCallTransformer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun findDelegate(fqName: FqName): FunctionDelegate? {
|
private fun findDelegate(fqName: FqName): FunctionDelegate? {
|
||||||
return context.findOverloads(fqName)
|
return context.referenceFunctions(fqName)
|
||||||
.mapNotNull { overload ->
|
.mapNotNull { overload ->
|
||||||
// TODO allow other signatures than (Boolean, String) and (Boolean, () -> String)
|
// TODO allow other signatures than (Boolean, String) and (Boolean, () -> String)
|
||||||
val parameters = overload.owner.valueParameters
|
val parameters = overload.owner.valueParameters
|
||||||
@@ -179,10 +168,10 @@ class PowerAssertCallTransformer(
|
|||||||
object : FunctionDelegate {
|
object : FunctionDelegate {
|
||||||
override fun buildCall(builder: IrBuilderWithScope, original: IrCall, message: IrExpression): IrExpression = with(builder) {
|
override fun buildCall(builder: IrBuilderWithScope, original: IrCall, message: IrExpression): IrExpression = with(builder) {
|
||||||
val scope = this
|
val scope = this
|
||||||
val lambda = buildFun {
|
val lambda = builder.context.irFactory.buildFun {
|
||||||
name = Name.special("<anonymous>")
|
name = Name.special("<anonymous>")
|
||||||
returnType = context.irBuiltIns.stringType
|
returnType = context.irBuiltIns.stringType
|
||||||
visibility = Visibilities.LOCAL
|
visibility = DescriptorVisibilities.LOCAL
|
||||||
origin = IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA
|
origin = IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA
|
||||||
}.apply {
|
}.apply {
|
||||||
val bodyBuilder = DeclarationIrBuilder(this@PowerAssertCallTransformer.context, symbol)
|
val bodyBuilder = DeclarationIrBuilder(this@PowerAssertCallTransformer.context, symbol)
|
||||||
@@ -220,9 +209,22 @@ class PowerAssertCallTransformer(
|
|||||||
|
|
||||||
private fun isStringSupertype(type: IrType): Boolean =
|
private fun isStringSupertype(type: IrType): Boolean =
|
||||||
context.irBuiltIns.stringType.isSubtypeOf(type, context.irBuiltIns)
|
context.irBuiltIns.stringType.isSubtypeOf(type, context.irBuiltIns)
|
||||||
}
|
|
||||||
|
|
||||||
// TODO is this the best way to find overload functions?
|
private fun MessageCollector.info(expression: IrElement, message: String) {
|
||||||
private fun IrPluginContext.findOverloads(fqName: FqName): List<IrFunctionSymbol> {
|
report(expression, CompilerMessageSeverity.INFO, message)
|
||||||
return referenceFunctions(fqName).toList()
|
}
|
||||||
|
|
||||||
|
private fun MessageCollector.warn(expression: IrElement, message: String) {
|
||||||
|
report(expression, CompilerMessageSeverity.WARNING, message)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun MessageCollector.report(expression: IrElement, severity: CompilerMessageSeverity, message: String) {
|
||||||
|
report(severity, message, expression.toCompilerMessageLocation())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IrElement.toCompilerMessageLocation(): CompilerMessageLocation {
|
||||||
|
val info = file.info(this)
|
||||||
|
val lineContent = fileSource.substring(this)
|
||||||
|
return CompilerMessageLocation.create(file.path, info.startLineNumber, info.startColumnNumber, lineContent)!!
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-4
@@ -2,7 +2,7 @@
|
|||||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*
|
*
|
||||||
* Copied from https://github.com/JetBrains/kotlin/blob/1.4.0/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/ReturnableBlockLowering.kt
|
* Copied from https://github.com/JetBrains/kotlin/blob/1.4.20/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/ReturnableBlockLowering.kt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.bnorm.power.internal
|
package com.bnorm.power.internal
|
||||||
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.ir.expressions.*
|
|||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.transformStatement
|
||||||
|
|
||||||
// TODO Remove when inlining works correctly on Kotlin/JS and Kotlin/Native
|
// TODO Remove when inlining works correctly on Kotlin/JS and Kotlin/Native
|
||||||
class ReturnableBlockTransformer(val context: IrGeneratorContext, val containerSymbol: IrSymbol? = null) : IrElementTransformerVoidWithContext() {
|
class ReturnableBlockTransformer(val context: IrGeneratorContext, val containerSymbol: IrSymbol? = null) : IrElementTransformerVoidWithContext() {
|
||||||
@@ -52,7 +53,7 @@ class ReturnableBlockTransformer(val context: IrGeneratorContext, val containerS
|
|||||||
returnMap[expression.symbol] = { returnExpression ->
|
returnMap[expression.symbol] = { returnExpression ->
|
||||||
hasReturned = true
|
hasReturned = true
|
||||||
builder.irComposite(returnExpression) {
|
builder.irComposite(returnExpression) {
|
||||||
+irSetVar(variable.symbol, returnExpression.value)
|
+irSet(variable.symbol, returnExpression.value)
|
||||||
+irBreak(loop)
|
+irBreak(loop)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -61,10 +62,10 @@ class ReturnableBlockTransformer(val context: IrGeneratorContext, val containerS
|
|||||||
if (i == expression.statements.lastIndex && s is IrReturn && s.returnTargetSymbol == expression.symbol) {
|
if (i == expression.statements.lastIndex && s is IrReturn && s.returnTargetSymbol == expression.symbol) {
|
||||||
s.transformChildrenVoid()
|
s.transformChildrenVoid()
|
||||||
if (!hasReturned) s.value else {
|
if (!hasReturned) s.value else {
|
||||||
builder.irSetVar(variable.symbol, s.value)
|
builder.irSet(variable.symbol, s.value)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
s.transform(this, null)
|
s.transformStatement(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
kotlin("multiplatform") version "1.4.0"
|
kotlin("multiplatform") version "1.4.20"
|
||||||
id("com.bnorm.power.kotlin-power-assert") version "0.5.3"
|
id("com.bnorm.power.kotlin-power-assert") version "0.5.3"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user