Merge pull request #17 from bnorm/kotlin-1.4

Kotlin 1.4
This commit is contained in:
Brian Norman
2020-08-20 19:27:23 -05:00
committed by GitHub
11 changed files with 79 additions and 124 deletions
+1 -1
View File
@@ -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 {
@@ -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)
}
}
}
} }
@@ -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)
}
}
}
+2 -2
View File
@@ -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
View File
@@ -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"))