Update to Kotlin 1.3.70
This commit is contained in:
+1
-1
@@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
kotlin("jvm") version "1.3.60" apply false
|
||||
kotlin("jvm") version "1.3.70" apply false
|
||||
id("org.jetbrains.dokka") version "0.10.0" apply false
|
||||
id("com.gradle.plugin-publish") version "0.10.1" apply false
|
||||
}
|
||||
|
||||
@@ -11,14 +11,14 @@ plugins {
|
||||
|
||||
dependencies {
|
||||
implementation(kotlin("stdlib-jdk8"))
|
||||
compileOnly("org.jetbrains.kotlin:kotlin-compiler-embeddable:1.3.60")
|
||||
compileOnly("org.jetbrains.kotlin:kotlin-compiler-embeddable:1.3.70")
|
||||
|
||||
kapt("com.google.auto.service:auto-service:1.0-rc6")
|
||||
compileOnly("com.google.auto.service:auto-service-annotations:1.0-rc6")
|
||||
|
||||
testImplementation(kotlin("test-junit"))
|
||||
testImplementation("org.jetbrains.kotlin:kotlin-compiler-embeddable:1.3.60")
|
||||
testImplementation("com.github.tschuchortdev:kotlin-compile-testing:1.2.5")
|
||||
testImplementation("org.jetbrains.kotlin:kotlin-compiler-embeddable:1.3.70")
|
||||
testImplementation("com.github.tschuchortdev:kotlin-compile-testing:1.2.6")
|
||||
}
|
||||
|
||||
tasks.withType<KotlinCompile> {
|
||||
|
||||
@@ -101,7 +101,7 @@ fun buildAssertTree(expression: IrExpression): RootNode {
|
||||
}
|
||||
|
||||
override fun visitCall(expression: IrCall, data: Node) {
|
||||
if (expression.descriptor.name.asString() == "EQEQ" && expression.origin == IrStatementOrigin.EXCLEQ) {
|
||||
if (expression.symbol.descriptor.name.asString() == "EQEQ" && expression.origin == IrStatementOrigin.EXCLEQ) {
|
||||
// Skip the EQEQ part of a EXCLEQ call
|
||||
expression.acceptChildren(this, data)
|
||||
} else {
|
||||
|
||||
@@ -16,11 +16,9 @@
|
||||
|
||||
package com.bnorm.power
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.lower.irThrow
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
|
||||
import org.jetbrains.kotlin.ir.builders.irCall
|
||||
import org.jetbrains.kotlin.ir.builders.irConcat
|
||||
import org.jetbrains.kotlin.ir.builders.irGet
|
||||
import org.jetbrains.kotlin.ir.builders.irString
|
||||
@@ -29,8 +27,6 @@ import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.expressions.IrThrow
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
|
||||
data class IrStackVariable(
|
||||
val temporary: IrVariable,
|
||||
@@ -44,13 +40,6 @@ data class ValueDisplay(
|
||||
val source: String
|
||||
)
|
||||
|
||||
fun IrBuilderWithScope.buildThrow(
|
||||
constructor: IrConstructorSymbol,
|
||||
message: IrExpression
|
||||
): IrThrow = irThrow(irCall(constructor).apply {
|
||||
putValueArgument(0, message)
|
||||
})
|
||||
|
||||
fun IrBuilderWithScope.buildMessage(
|
||||
file: IrFile,
|
||||
fileSource: String,
|
||||
@@ -74,7 +63,7 @@ fun IrBuilderWithScope.buildMessage(
|
||||
|
||||
val columnOffset: Int = when (original) {
|
||||
is IrMemberAccessExpression -> {
|
||||
val descriptor = original.descriptor
|
||||
val descriptor = original.symbol.descriptor
|
||||
when {
|
||||
descriptor is FunctionDescriptor && descriptor.isInfix -> source.indexOf(descriptor.name.asString())
|
||||
else -> when (original.origin) {
|
||||
|
||||
@@ -16,13 +16,16 @@
|
||||
|
||||
package com.bnorm.power
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
||||
import org.jetbrains.kotlin.backend.common.ir.asSimpleLambda
|
||||
import org.jetbrains.kotlin.backend.common.ir.inline
|
||||
import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.lower.at
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.serialization.findPackage
|
||||
import org.jetbrains.kotlin.builtins.isBuiltinFunctionalType
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
@@ -36,7 +39,6 @@ import org.jetbrains.kotlin.ir.builders.irReturn
|
||||
import org.jetbrains.kotlin.ir.builders.irString
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.path
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConst
|
||||
@@ -46,16 +48,14 @@ import org.jetbrains.kotlin.ir.expressions.IrStringConcatenation
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionExpressionImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.getClass
|
||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||
import org.jetbrains.kotlin.ir.util.functions
|
||||
import org.jetbrains.kotlin.ir.util.getPackageFragment
|
||||
import org.jetbrains.kotlin.ir.util.referenceFunction
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.isBoolean
|
||||
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
||||
@@ -76,9 +76,9 @@ fun FileLoweringPass.runOnFileInOrder(irFile: IrFile) {
|
||||
}
|
||||
|
||||
class PowerAssertCallTransformer(
|
||||
private val context: BackendContext,
|
||||
private val context: IrPluginContext,
|
||||
private val functions: Set<FqName>
|
||||
) : IrElementTransformerVoid(), FileLoweringPass {
|
||||
) : IrElementTransformerVoidWithContext(), FileLoweringPass {
|
||||
private lateinit var file: IrFile
|
||||
private lateinit var fileSource: String
|
||||
|
||||
@@ -90,8 +90,8 @@ class PowerAssertCallTransformer(
|
||||
}
|
||||
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
val function = expression.symbol.owner
|
||||
if (functions.none { function.fqNameWhenAvailable == it })
|
||||
val function = expression.symbol.descriptor
|
||||
if (functions.none { function.fqNameSafe == it })
|
||||
return super.visitCall(expression)
|
||||
|
||||
val delegate = findDelegate(function) ?: run {
|
||||
@@ -103,24 +103,26 @@ class PowerAssertCallTransformer(
|
||||
val assertionArgument = expression.getValueArgument(0)!!
|
||||
val messageArgument = if (function.valueParameters.size == 2) expression.getValueArgument(1) else null
|
||||
|
||||
context.createIrBuilder(expression.symbol).run {
|
||||
val symbol = currentScope!!.scope.scopeOwnerSymbol
|
||||
DeclarationIrBuilder(context, symbol).run {
|
||||
at(expression)
|
||||
|
||||
val lambda = messageArgument?.asSimpleLambda()
|
||||
val title = when {
|
||||
messageArgument is IrConst<*> -> messageArgument
|
||||
messageArgument is IrStringConcatenation -> messageArgument
|
||||
lambda != null -> lambda.inline()
|
||||
messageArgument != null -> {
|
||||
val invoke = messageArgument.type.getClass()!!.functions.single { it.name == OperatorNameConventions.INVOKE }
|
||||
irCallOp(invoke.symbol, invoke.returnType, messageArgument)
|
||||
}
|
||||
// TODO what should the default message be?
|
||||
else -> irString("Assertion failed")
|
||||
}
|
||||
|
||||
val generator = object : PowerAssertGenerator() {
|
||||
override fun IrBuilderWithScope.buildAssertThrow(subStack: List<IrStackVariable>): IrExpression {
|
||||
|
||||
val lambda = messageArgument?.asSimpleLambda()
|
||||
val title = when {
|
||||
messageArgument is IrConst<*> -> messageArgument
|
||||
messageArgument is IrStringConcatenation -> messageArgument
|
||||
lambda != null -> lambda.inline()
|
||||
messageArgument != null -> {
|
||||
val invoke = messageArgument.type.getClass()!!.functions.single { it.name == OperatorNameConventions.INVOKE }
|
||||
irCallOp(invoke.symbol, invoke.returnType, messageArgument)
|
||||
}
|
||||
// TODO what should the default message be?
|
||||
else -> irString("Assertion failed")
|
||||
}
|
||||
|
||||
return delegate.buildCall(this, buildMessage(file, fileSource, title, expression, subStack))
|
||||
}
|
||||
}
|
||||
@@ -140,7 +142,9 @@ class PowerAssertCallTransformer(
|
||||
fun buildCall(builder: IrBuilderWithScope, message: IrExpression): IrExpression
|
||||
}
|
||||
|
||||
private fun findDelegate(function: IrFunction): FunctionDelegate? {
|
||||
private fun findDelegate(function: FunctionDescriptor): FunctionDelegate? {
|
||||
fun KotlinType.toIrType() = context.typeTranslator.translateType(this)
|
||||
|
||||
return context.findOverloads(function)
|
||||
.mapNotNull { overload ->
|
||||
// TODO allow other signatures than (Boolean, String) and (Boolean, () -> String))
|
||||
@@ -152,7 +156,7 @@ class PowerAssertCallTransformer(
|
||||
isStringSupertype(parameters[1].type) -> {
|
||||
object : FunctionDelegate {
|
||||
override fun buildCall(builder: IrBuilderWithScope, message: IrExpression): IrExpression = with(builder) {
|
||||
irCall(overload).apply {
|
||||
irCall(overload, type = overload.descriptor.returnType!!.toIrType()).apply {
|
||||
putValueArgument(0, irFalse())
|
||||
putValueArgument(1, message)
|
||||
}
|
||||
@@ -168,13 +172,13 @@ class PowerAssertCallTransformer(
|
||||
visibility = Visibilities.LOCAL
|
||||
origin = IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA
|
||||
}.apply {
|
||||
val bodyBuilder = this@PowerAssertCallTransformer.context.createIrBuilder(symbol)
|
||||
val bodyBuilder = DeclarationIrBuilder(this@PowerAssertCallTransformer.context, symbol)
|
||||
body = bodyBuilder.irBlockBody {
|
||||
+irReturn(message)
|
||||
}
|
||||
}
|
||||
val expression = IrFunctionExpressionImpl(-1, -1, context.irBuiltIns.stringType, lambda, IrStatementOrigin.LAMBDA)
|
||||
irCall(overload).apply {
|
||||
irCall(overload, type = overload.descriptor.returnType!!.toIrType()).apply {
|
||||
putValueArgument(0, irFalse())
|
||||
putValueArgument(1, expression)
|
||||
}
|
||||
@@ -195,7 +199,7 @@ class PowerAssertCallTransformer(
|
||||
}
|
||||
|
||||
// TODO is this the best way to find overload functions?
|
||||
private fun BackendContext.findOverloads(function: IrFunction): List<IrFunctionSymbol> =
|
||||
function.getPackageFragment()!!.symbol.descriptor.getMemberScope()
|
||||
private fun IrPluginContext.findOverloads(function: FunctionDescriptor): List<IrFunctionSymbol> =
|
||||
function.findPackage().getMemberScope()
|
||||
.getContributedFunctions(function.name, NoLookupLocation.FROM_BACKEND)
|
||||
.map { ir.symbols.externalSymbolTable.referenceFunction(it) }
|
||||
.map { symbolTable.referenceFunction(it) }
|
||||
|
||||
+6
-5
@@ -16,16 +16,17 @@
|
||||
|
||||
package com.bnorm.power
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
class PowerAssertIrGenerationExtension(
|
||||
private val functions: Set<FqName>
|
||||
) : IrGenerationExtension {
|
||||
override fun generate(file: IrFile, backendContext: BackendContext, bindingContext: BindingContext) {
|
||||
PowerAssertCallTransformer(backendContext, functions).runOnFileInOrder(file)
|
||||
override fun generate(moduleFragment: IrModuleFragment, pluginContext: IrPluginContext) {
|
||||
for (file in moduleFragment.files) {
|
||||
PowerAssertCallTransformer(pluginContext, functions).runOnFileInOrder(file)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,7 +345,7 @@ assertTrue(1 == 2, message = "${"$"}text, the world is broken")
|
||||
|
|
||||
false
|
||||
""".trimIndent(),
|
||||
PowerAssertComponentRegistrar(setOf(FqName("kotlin.test.AssertionsKt.assertTrue")))
|
||||
PowerAssertComponentRegistrar(setOf(FqName("kotlin.test.assertTrue")))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -362,7 +362,7 @@ require(1 == 2) { "the world is broken" }
|
||||
|
|
||||
false
|
||||
""".trimIndent(),
|
||||
PowerAssertComponentRegistrar(setOf(FqName("kotlin.PreconditionsKt.require")))
|
||||
PowerAssertComponentRegistrar(setOf(FqName("kotlin.require")))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -379,7 +379,7 @@ check(1 == 2) { "the world is broken" }
|
||||
|
|
||||
false
|
||||
""".trimIndent(),
|
||||
PowerAssertComponentRegistrar(setOf(FqName("kotlin.PreconditionsKt.check")))
|
||||
PowerAssertComponentRegistrar(setOf(FqName("kotlin.check")))
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -387,7 +387,7 @@ check(1 == 2) { "the world is broken" }
|
||||
fun assertMessage(
|
||||
@Language("kotlin") source: String,
|
||||
message: String,
|
||||
vararg plugins: ComponentRegistrar = arrayOf(PowerAssertComponentRegistrar(setOf(FqName("kotlin.PreconditionsKt.assert"))))
|
||||
vararg plugins: ComponentRegistrar = arrayOf(PowerAssertComponentRegistrar(setOf(FqName("kotlin.assert"))))
|
||||
) {
|
||||
val result = KotlinCompilation().apply {
|
||||
sources = listOf(SourceFile.kotlin("main.kt", source))
|
||||
@@ -400,7 +400,7 @@ fun assertMessage(
|
||||
assertEquals(KotlinCompilation.ExitCode.OK, result.exitCode)
|
||||
|
||||
val kClazz = result.classLoader.loadClass("MainKt")
|
||||
val main = kClazz.declaredMethods.single { it.name == "main" }
|
||||
val main = kClazz.declaredMethods.single { it.name == "main" && it.parameterCount == 0 }
|
||||
try {
|
||||
try {
|
||||
main.invoke(null)
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
buildscript {
|
||||
dependencies {
|
||||
classpath("gradle.plugin.com.bnorm.power:kotlin-power-assert-gradle:0.1.0")
|
||||
classpath("gradle.plugin.com.bnorm.power:kotlin-power-assert-gradle:0.2.0")
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
kotlin("jvm") version "1.3.60"
|
||||
kotlin("jvm") version "1.3.70"
|
||||
}
|
||||
apply(plugin = "com.bnorm.power.kotlin-power-assert")
|
||||
|
||||
@@ -16,7 +16,6 @@ repositories {
|
||||
dependencies {
|
||||
implementation(kotlin("stdlib-jdk8"))
|
||||
testImplementation(kotlin("test-junit"))
|
||||
testImplementation("org.assertj:assertj-core:3.15.0")
|
||||
}
|
||||
|
||||
tasks.compileTestKotlin {
|
||||
@@ -25,5 +24,5 @@ tasks.compileTestKotlin {
|
||||
}
|
||||
|
||||
configure<com.bnorm.power.PowerAssertGradleExtension> {
|
||||
functions = listOf("kotlin.test.AssertionsKt.assertTrue", "kotlin.PreconditionsKt.require")
|
||||
functions = listOf("kotlin.test.assertTrue", "kotlin.require")
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ data class Person(
|
||||
)
|
||||
|
||||
class PowerAssertTest {
|
||||
private val people = listOf(Person("Brian", "Norman"), Person("Melinda", "Norman"))
|
||||
private val people = listOf(Person("John", "Doe"), Person("Jane", "Doe"))
|
||||
|
||||
@Test
|
||||
fun assertTrue() {
|
||||
|
||||
Reference in New Issue
Block a user