+1
-1
@@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm") version "1.3.70" apply false
|
kotlin("jvm") version "1.4.0" 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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
|||||||
plugins {
|
plugins {
|
||||||
id("java-gradle-plugin")
|
id("java-gradle-plugin")
|
||||||
kotlin("jvm")
|
kotlin("jvm")
|
||||||
kotlin("kapt")
|
|
||||||
|
|
||||||
id("com.gradle.plugin-publish")
|
id("com.gradle.plugin-publish")
|
||||||
}
|
}
|
||||||
@@ -11,9 +10,6 @@ plugins {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation(kotlin("stdlib"))
|
implementation(kotlin("stdlib"))
|
||||||
implementation(kotlin("gradle-plugin-api"))
|
implementation(kotlin("gradle-plugin-api"))
|
||||||
|
|
||||||
kapt("com.google.auto.service:auto-service:1.0-rc6")
|
|
||||||
compileOnly("com.google.auto.service:auto-service-annotations:1.0-rc6")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pluginBundle {
|
pluginBundle {
|
||||||
|
|||||||
+29
-3
@@ -16,11 +16,37 @@
|
|||||||
|
|
||||||
package com.bnorm.power
|
package com.bnorm.power
|
||||||
|
|
||||||
import org.gradle.api.Plugin
|
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.provider.Provider
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerPluginSupportPlugin
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.SubpluginArtifact
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.SubpluginOption
|
||||||
|
|
||||||
class PowerAssertGradlePlugin : Plugin<Project> {
|
class PowerAssertGradlePlugin : KotlinCompilerPluginSupportPlugin {
|
||||||
override fun apply(project: Project): Unit = with(project) {
|
override fun apply(target: Project): Unit = with(target) {
|
||||||
extensions.create("kotlinPowerAssert", PowerAssertGradleExtension::class.java)
|
extensions.create("kotlinPowerAssert", PowerAssertGradleExtension::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isApplicable(kotlinCompilation: KotlinCompilation<*>): Boolean = true
|
||||||
|
|
||||||
|
override fun getCompilerPluginId(): String = "com.bnorm.kotlin-power-assert"
|
||||||
|
|
||||||
|
override fun getPluginArtifact(): SubpluginArtifact = SubpluginArtifact(
|
||||||
|
groupId = "com.bnorm.power",
|
||||||
|
artifactId = "kotlin-power-assert",
|
||||||
|
version = "0.4.0-SNAPSHOT"
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun applyToCompilation(
|
||||||
|
kotlinCompilation: KotlinCompilation<*>
|
||||||
|
): Provider<List<SubpluginOption>> {
|
||||||
|
val project = kotlinCompilation.target.project
|
||||||
|
val extension = project.extensions.getByType(PowerAssertGradleExtension::class.java)
|
||||||
|
return project.provider {
|
||||||
|
extension.functions.map {
|
||||||
|
SubpluginOption(key = "function", value = it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
-58
@@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2020 Brian Norman
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.bnorm.power
|
|
||||||
|
|
||||||
import com.google.auto.service.AutoService
|
|
||||||
import org.gradle.api.Project
|
|
||||||
import org.gradle.api.tasks.compile.AbstractCompile
|
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
|
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin
|
|
||||||
import org.jetbrains.kotlin.gradle.plugin.SubpluginArtifact
|
|
||||||
import org.jetbrains.kotlin.gradle.plugin.SubpluginOption
|
|
||||||
|
|
||||||
@AutoService(KotlinGradleSubplugin::class)
|
|
||||||
class PowerAssertGradleSubplugin : KotlinGradleSubplugin<AbstractCompile> {
|
|
||||||
|
|
||||||
override fun getCompilerPluginId(): String = "com.bnorm.kotlin-power-assert"
|
|
||||||
|
|
||||||
override fun isApplicable(project: Project, task: AbstractCompile): Boolean =
|
|
||||||
project.plugins.hasPlugin(PowerAssertGradlePlugin::class.java)
|
|
||||||
|
|
||||||
|
|
||||||
override fun getPluginArtifact(): SubpluginArtifact = SubpluginArtifact(
|
|
||||||
groupId = "com.bnorm.power",
|
|
||||||
artifactId = "kotlin-power-assert",
|
|
||||||
version = "0.4.0-SNAPSHOT"
|
|
||||||
)
|
|
||||||
|
|
||||||
override fun apply(
|
|
||||||
project: Project,
|
|
||||||
kotlinCompile: AbstractCompile,
|
|
||||||
javaCompile: AbstractCompile?,
|
|
||||||
variantData: Any?,
|
|
||||||
androidProjectHandler: Any?,
|
|
||||||
kotlinCompilation: KotlinCompilation<KotlinCommonOptions>?
|
|
||||||
): List<SubpluginOption> {
|
|
||||||
val extension = project.extensions.findByType(PowerAssertGradleExtension::class.java)
|
|
||||||
?: PowerAssertGradleExtension()
|
|
||||||
|
|
||||||
return extension.functions.map {
|
|
||||||
SubpluginOption(key = "function", value = it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -11,13 +11,13 @@ plugins {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(kotlin("stdlib-jdk8"))
|
implementation(kotlin("stdlib-jdk8"))
|
||||||
compileOnly("org.jetbrains.kotlin:kotlin-compiler-embeddable:1.3.70")
|
compileOnly("org.jetbrains.kotlin:kotlin-compiler-embeddable")
|
||||||
|
|
||||||
kapt("com.google.auto.service:auto-service:1.0-rc6")
|
kapt("com.google.auto.service:auto-service:1.0-rc6")
|
||||||
compileOnly("com.google.auto.service:auto-service-annotations:1.0-rc6")
|
compileOnly("com.google.auto.service:auto-service-annotations:1.0-rc6")
|
||||||
|
|
||||||
testImplementation(kotlin("test-junit"))
|
testImplementation(kotlin("test-junit"))
|
||||||
testImplementation("org.jetbrains.kotlin:kotlin-compiler-embeddable:1.3.70")
|
testImplementation("org.jetbrains.kotlin:kotlin-compiler-embeddable")
|
||||||
testImplementation("com.github.tschuchortdev:kotlin-compile-testing:1.2.6")
|
testImplementation("com.github.tschuchortdev:kotlin-compile-testing:1.2.6")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,13 +16,14 @@
|
|||||||
|
|
||||||
package com.bnorm.power
|
package com.bnorm.power
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.deepCopyWithVariables
|
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrConst
|
import org.jetbrains.kotlin.ir.expressions.IrConst
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrWhen
|
import org.jetbrains.kotlin.ir.expressions.IrWhen
|
||||||
|
import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
|
|
||||||
sealed class Node {
|
sealed class Node {
|
||||||
@@ -31,7 +32,7 @@ sealed class Node {
|
|||||||
val children: List<Node> get() = mutableChildren
|
val children: List<Node> get() = mutableChildren
|
||||||
|
|
||||||
protected fun dump(builder: StringBuilder, indent: Int) {
|
protected fun dump(builder: StringBuilder, indent: Int) {
|
||||||
builder.append(" ".repeat(indent)).append(this).appendln()
|
builder.append(" ".repeat(indent)).append(this).appendLine()
|
||||||
for (child in children) {
|
for (child in children) {
|
||||||
child.dump(builder, indent + 1)
|
child.dump(builder, indent + 1)
|
||||||
}
|
}
|
||||||
@@ -67,10 +68,10 @@ class ExpressionNode(
|
|||||||
_expressions.add(expression)
|
_expressions.add(expression)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getExpressionsCopy(): List<IrExpression> {
|
fun getExpressionsCopy(initialParent: IrDeclarationParent?): List<IrExpression> {
|
||||||
// Return a copy of all the expression by creating a deep copy of the head
|
// Return a copy of all the expression by creating a deep copy of the head
|
||||||
// expression and running back through the assertion tree builder
|
// expression and running back through the assertion tree builder
|
||||||
val headCopy = _expressions.first().deepCopyWithVariables()
|
val headCopy = _expressions.first().deepCopyWithSymbols(initialParent)
|
||||||
return (buildAssertTree(headCopy).children.single() as ExpressionNode)._expressions
|
return (buildAssertTree(headCopy).children.single() as ExpressionNode)._expressions
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,7 +102,7 @@ fun buildAssertTree(expression: IrExpression): RootNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitCall(expression: IrCall, data: Node) {
|
override fun visitCall(expression: IrCall, data: Node) {
|
||||||
if (expression.symbol.descriptor.name.asString() == "EQEQ" && expression.origin == IrStatementOrigin.EXCLEQ) {
|
if (expression.symbol.owner.name.asString() == "EQEQ" && expression.origin == IrStatementOrigin.EXCLEQ) {
|
||||||
// Skip the EQEQ part of a EXCLEQ call
|
// Skip the EQEQ part of a EXCLEQ call
|
||||||
expression.acceptChildren(this, data)
|
expression.acceptChildren(this, data)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ fun IrBuilderWithScope.buildMessage(
|
|||||||
|
|
||||||
val columnOffset: Int = when (original) {
|
val columnOffset: Int = when (original) {
|
||||||
is IrMemberAccessExpression -> {
|
is IrMemberAccessExpression -> {
|
||||||
|
// TODO IrFunction doesn't have 'isInfix' as a property
|
||||||
val descriptor = original.symbol.descriptor
|
val descriptor = original.symbol.descriptor
|
||||||
when {
|
when {
|
||||||
descriptor is FunctionDescriptor && descriptor.isInfix -> source.indexOf(descriptor.name.asString())
|
descriptor is FunctionDescriptor && descriptor.isInfix -> source.indexOf(descriptor.name.asString())
|
||||||
|
|||||||
@@ -23,11 +23,7 @@ import org.jetbrains.kotlin.backend.common.ir.asSimpleLambda
|
|||||||
import org.jetbrains.kotlin.backend.common.ir.inline
|
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.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.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
|
||||||
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
|
||||||
@@ -37,6 +33,7 @@ import org.jetbrains.kotlin.ir.builders.irCallOp
|
|||||||
import org.jetbrains.kotlin.ir.builders.irFalse
|
import org.jetbrains.kotlin.ir.builders.irFalse
|
||||||
import org.jetbrains.kotlin.ir.builders.irReturn
|
import org.jetbrains.kotlin.ir.builders.irReturn
|
||||||
import org.jetbrains.kotlin.ir.builders.irString
|
import org.jetbrains.kotlin.ir.builders.irString
|
||||||
|
import org.jetbrains.kotlin.ir.builders.parent
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.declarations.path
|
import org.jetbrains.kotlin.ir.declarations.path
|
||||||
@@ -47,18 +44,21 @@ import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
|||||||
import org.jetbrains.kotlin.ir.expressions.IrStringConcatenation
|
import org.jetbrains.kotlin.ir.expressions.IrStringConcatenation
|
||||||
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.symbols.IrFunctionSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||||
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
|
import org.jetbrains.kotlin.ir.types.IrTypeArgument
|
||||||
|
import org.jetbrains.kotlin.ir.types.IrTypeProjection
|
||||||
import org.jetbrains.kotlin.ir.types.getClass
|
import org.jetbrains.kotlin.ir.types.getClass
|
||||||
|
import org.jetbrains.kotlin.ir.types.isBoolean
|
||||||
|
import org.jetbrains.kotlin.ir.types.isSubtypeOf
|
||||||
import org.jetbrains.kotlin.ir.util.functions
|
import org.jetbrains.kotlin.ir.util.functions
|
||||||
import org.jetbrains.kotlin.ir.util.referenceFunction
|
import org.jetbrains.kotlin.ir.util.isFunctionOrKFunction
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
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.resolve.descriptorUtil.fqNameSafe
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isBoolean
|
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@@ -90,16 +90,18 @@ class PowerAssertCallTransformer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitCall(expression: IrCall): IrExpression {
|
override fun visitCall(expression: IrCall): IrExpression {
|
||||||
val function = expression.symbol.descriptor
|
// TODO expression.symbol.owner.fqNameSafe includes the wrapping ClassKt while descriptor doesn't
|
||||||
if (functions.none { function.fqNameSafe == it })
|
val fqName = expression.symbol.descriptor.fqNameSafe
|
||||||
|
if (functions.none { fqName == it })
|
||||||
return super.visitCall(expression)
|
return super.visitCall(expression)
|
||||||
|
|
||||||
val delegate = findDelegate(function) ?: run {
|
val delegate = findDelegate(fqName) ?: run {
|
||||||
// Find a valid delegate function or do not translate
|
// Find a valid delegate function or do not translate
|
||||||
// TODO log a warning
|
// TODO log a warning
|
||||||
return super.visitCall(expression)
|
return super.visitCall(expression)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val function = expression.symbol.owner
|
||||||
val assertionArgument = expression.getValueArgument(0)!!
|
val assertionArgument = expression.getValueArgument(0)!!
|
||||||
val messageArgument = if (function.valueParameters.size == 2) expression.getValueArgument(1) else null
|
val messageArgument = if (function.valueParameters.size == 2) expression.getValueArgument(1) else null
|
||||||
|
|
||||||
@@ -114,7 +116,7 @@ class PowerAssertCallTransformer(
|
|||||||
val title = when {
|
val title = when {
|
||||||
messageArgument is IrConst<*> -> messageArgument
|
messageArgument is IrConst<*> -> messageArgument
|
||||||
messageArgument is IrStringConcatenation -> messageArgument
|
messageArgument is IrStringConcatenation -> messageArgument
|
||||||
lambda != null -> lambda.inline()
|
lambda != null -> lambda.inline(parent)
|
||||||
messageArgument != null -> {
|
messageArgument != null -> {
|
||||||
val invoke = messageArgument.type.getClass()!!.functions.single { it.name == OperatorNameConventions.INVOKE }
|
val invoke = messageArgument.type.getClass()!!.functions.single { it.name == OperatorNameConventions.INVOKE }
|
||||||
irCallOp(invoke.symbol, invoke.returnType, messageArgument)
|
irCallOp(invoke.symbol, invoke.returnType, messageArgument)
|
||||||
@@ -142,13 +144,11 @@ class PowerAssertCallTransformer(
|
|||||||
fun buildCall(builder: IrBuilderWithScope, message: IrExpression): IrExpression
|
fun buildCall(builder: IrBuilderWithScope, message: IrExpression): IrExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findDelegate(function: FunctionDescriptor): FunctionDelegate? {
|
private fun findDelegate(fqName: FqName): FunctionDelegate? {
|
||||||
fun KotlinType.toIrType() = context.typeTranslator.translateType(this)
|
return context.findOverloads(fqName)
|
||||||
|
|
||||||
return context.findOverloads(function)
|
|
||||||
.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.descriptor.valueParameters
|
val parameters = overload.owner.valueParameters
|
||||||
if (parameters.size != 2) return@mapNotNull null
|
if (parameters.size != 2) return@mapNotNull null
|
||||||
if (!parameters[0].type.isBoolean()) return@mapNotNull null
|
if (!parameters[0].type.isBoolean()) return@mapNotNull null
|
||||||
|
|
||||||
@@ -156,7 +156,7 @@ class PowerAssertCallTransformer(
|
|||||||
isStringSupertype(parameters[1].type) -> {
|
isStringSupertype(parameters[1].type) -> {
|
||||||
object : FunctionDelegate {
|
object : FunctionDelegate {
|
||||||
override fun buildCall(builder: IrBuilderWithScope, message: IrExpression): IrExpression = with(builder) {
|
override fun buildCall(builder: IrBuilderWithScope, message: IrExpression): IrExpression = with(builder) {
|
||||||
irCall(overload, type = overload.descriptor.returnType!!.toIrType()).apply {
|
irCall(overload, type = overload.owner.returnType).apply {
|
||||||
putValueArgument(0, irFalse())
|
putValueArgument(0, irFalse())
|
||||||
putValueArgument(1, message)
|
putValueArgument(1, message)
|
||||||
}
|
}
|
||||||
@@ -166,6 +166,7 @@ class PowerAssertCallTransformer(
|
|||||||
isStringFunction(parameters[1].type) -> {
|
isStringFunction(parameters[1].type) -> {
|
||||||
object : FunctionDelegate {
|
object : FunctionDelegate {
|
||||||
override fun buildCall(builder: IrBuilderWithScope, message: IrExpression): IrExpression = with(builder) {
|
override fun buildCall(builder: IrBuilderWithScope, message: IrExpression): IrExpression = with(builder) {
|
||||||
|
val scope = this
|
||||||
val lambda = buildFun {
|
val lambda = buildFun {
|
||||||
name = Name.special("<anonymous>")
|
name = Name.special("<anonymous>")
|
||||||
returnType = context.irBuiltIns.stringType
|
returnType = context.irBuiltIns.stringType
|
||||||
@@ -176,30 +177,35 @@ class PowerAssertCallTransformer(
|
|||||||
body = bodyBuilder.irBlockBody {
|
body = bodyBuilder.irBlockBody {
|
||||||
+irReturn(message)
|
+irReturn(message)
|
||||||
}
|
}
|
||||||
|
parent = scope.parent
|
||||||
}
|
}
|
||||||
val expression = IrFunctionExpressionImpl(-1, -1, context.irBuiltIns.stringType, lambda, IrStatementOrigin.LAMBDA)
|
val expression = IrFunctionExpressionImpl(-1, -1, context.irBuiltIns.stringType, lambda, IrStatementOrigin.LAMBDA)
|
||||||
irCall(overload, type = overload.descriptor.returnType!!.toIrType()).apply {
|
irCall(overload, type = overload.owner.returnType).apply {
|
||||||
putValueArgument(0, irFalse())
|
putValueArgument(0, irFalse())
|
||||||
putValueArgument(1, expression)
|
putValueArgument(1, expression)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> null
|
else -> {
|
||||||
|
null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isStringFunction(type: KotlinType): Boolean =
|
private fun isStringFunction(type: IrType): Boolean =
|
||||||
type.isBuiltinFunctionalType && type.arguments.size == 1 && isStringSupertype(type.arguments.first().type)
|
type.isFunctionOrKFunction() && type is IrSimpleType && (type.arguments.size == 1 && isStringSupertype(type.arguments.first()))
|
||||||
|
|
||||||
private fun isStringSupertype(type: KotlinType): Boolean =
|
private fun isStringSupertype(argument: IrTypeArgument): Boolean =
|
||||||
context.builtIns.stringType.isSubtypeOf(type)
|
argument is IrTypeProjection && isStringSupertype(argument.type)
|
||||||
|
|
||||||
|
private fun isStringSupertype(type: IrType): Boolean =
|
||||||
|
context.irBuiltIns.stringType.isSubtypeOf(type, context.irBuiltIns)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO is this the best way to find overload functions?
|
// TODO is this the best way to find overload functions?
|
||||||
private fun IrPluginContext.findOverloads(function: FunctionDescriptor): List<IrFunctionSymbol> =
|
private fun IrPluginContext.findOverloads(fqName: FqName): List<IrFunctionSymbol> {
|
||||||
function.findPackage().getMemberScope()
|
return referenceFunctions(fqName).toList()
|
||||||
.getContributedFunctions(function.name, NoLookupLocation.FROM_BACKEND)
|
}
|
||||||
.map { symbolTable.referenceFunction(it) }
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ class PowerAssertCommandLineProcessor : CommandLineProcessor {
|
|||||||
optionName = "function",
|
optionName = "function",
|
||||||
valueDescription = "function full-qualified name",
|
valueDescription = "function full-qualified name",
|
||||||
description = "fully qualified path of function to intercept",
|
description = "fully qualified path of function to intercept",
|
||||||
|
required = false, // TODO required for Kotlin/JS
|
||||||
allowMultipleOccurrences = true
|
allowMultipleOccurrences = true
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.ir.builders.IrStatementsBuilder
|
|||||||
import org.jetbrains.kotlin.ir.builders.irBlock
|
import org.jetbrains.kotlin.ir.builders.irBlock
|
||||||
import org.jetbrains.kotlin.ir.builders.irGet
|
import org.jetbrains.kotlin.ir.builders.irGet
|
||||||
import org.jetbrains.kotlin.ir.builders.irTemporary
|
import org.jetbrains.kotlin.ir.builders.irTemporary
|
||||||
|
import org.jetbrains.kotlin.ir.builders.parent
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrGetValue
|
import org.jetbrains.kotlin.ir.expressions.IrGetValue
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrWhen
|
import org.jetbrains.kotlin.ir.expressions.IrWhen
|
||||||
@@ -75,13 +76,13 @@ abstract class PowerAssertGenerator {
|
|||||||
node: ExpressionNode,
|
node: ExpressionNode,
|
||||||
thenPart: IrStatementsBuilder<*>.(subStack: MutableList<IrStackVariable>) -> IrExpression
|
thenPart: IrStatementsBuilder<*>.(subStack: MutableList<IrStackVariable>) -> IrExpression
|
||||||
): IrWhen {
|
): IrWhen {
|
||||||
val expressions = node.getExpressionsCopy()
|
val expressions = node.getExpressionsCopy(this.parent)
|
||||||
val stackTransformer = StackBuilder(this, stack, expressions)
|
val stackTransformer = StackBuilder(this, stack, expressions)
|
||||||
val transformed = expressions.first().transform(stackTransformer, null)
|
val transformed = expressions.first().transform(stackTransformer, null)
|
||||||
return irIfThen(irNot(transformed), thenPart(stack.toMutableList()))
|
return irIfThen(irNot(transformed), thenPart(stack.toMutableList()))
|
||||||
}
|
}
|
||||||
|
|
||||||
inner class StackBuilder(
|
class StackBuilder(
|
||||||
private val builder: IrStatementsBuilder<*>,
|
private val builder: IrStatementsBuilder<*>,
|
||||||
private val stack: MutableList<IrStackVariable>,
|
private val stack: MutableList<IrStackVariable>,
|
||||||
private val transform: List<IrExpression>
|
private val transform: List<IrExpression>
|
||||||
|
|||||||
+2
-21
@@ -5,7 +5,7 @@ buildscript {
|
|||||||
}
|
}
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
kotlin("multiplatform") version "1.3.70"
|
kotlin("multiplatform") version "1.4.0"
|
||||||
}
|
}
|
||||||
apply(plugin = "com.bnorm.power.kotlin-power-assert")
|
apply(plugin = "com.bnorm.power.kotlin-power-assert")
|
||||||
|
|
||||||
@@ -23,15 +23,9 @@ kotlin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
js {
|
js(IR) {
|
||||||
browser()
|
browser()
|
||||||
nodejs()
|
nodejs()
|
||||||
|
|
||||||
compilations.all {
|
|
||||||
kotlinOptions {
|
|
||||||
kotlinOptions.freeCompilerArgs += listOf("-Xir-produce-klib-dir", "-Xir-produce-js")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val osName = System.getProperty("os.name")
|
val osName = System.getProperty("os.name")
|
||||||
@@ -43,9 +37,6 @@ kotlin {
|
|||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
val commonMain by getting {
|
val commonMain by getting {
|
||||||
dependencies {
|
|
||||||
implementation(kotlin("stdlib"))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
val commonTest by getting {
|
val commonTest by getting {
|
||||||
dependencies {
|
dependencies {
|
||||||
@@ -53,21 +44,11 @@ kotlin {
|
|||||||
implementation(kotlin("test-annotations-common"))
|
implementation(kotlin("test-annotations-common"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val jvmMain by getting {
|
|
||||||
dependencies {
|
|
||||||
implementation(kotlin("stdlib-jdk8"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val jvmTest by getting {
|
val jvmTest by getting {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(kotlin("test-junit"))
|
implementation(kotlin("test-junit"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val jsMain by getting {
|
|
||||||
dependencies {
|
|
||||||
implementation(kotlin("stdlib-js"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val jsTest by getting {
|
val jsTest by getting {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(kotlin("test-js"))
|
implementation(kotlin("test-js"))
|
||||||
|
|||||||
Reference in New Issue
Block a user