Skip to content
This repository was archived by the owner on Jan 20, 2023. It is now read-only.

Commit 12e6e29

Browse files
authored
Merge pull request #14 from k163377/update_kotlin
Update Kotlin and Improvement of initialization process.
2 parents cefe218 + 5465444 commit 12e6e29

File tree

11 files changed

+644
-147
lines changed

11 files changed

+644
-147
lines changed

.idea/codeStyles/codeStyleConfig.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

benchmark-results.csv

Lines changed: 103 additions & 103 deletions
Large diffs are not rendered by default.

build.gradle.kts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
plugins {
22
id("maven")
3-
kotlin("jvm") version "1.4.20"
3+
kotlin("jvm") version "1.4.21"
44
// プロダクションコード以外
55
id("org.jlleitschuh.gradle.ktlint") version "9.4.1"
66
id("jacoco")
@@ -22,6 +22,7 @@ dependencies {
2222
testImplementation(group = "org.junit.jupiter", name = "junit-jupiter", version = "5.7.0") {
2323
exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
2424
}
25+
testImplementation("io.mockk:mockk:1.10.3-jdk8")
2526

2627
implementation(group = "org.openjdk.jmh", name = "jmh-core", version = "1.26")
2728
}

src/main/kotlin/com/mapk/fastkfunction/FastKFunction.kt

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import com.mapk.fastkfunction.argumentbucket.BucketGenerator
55
import com.mapk.fastkfunction.spreadwrapper.ForConstructor
66
import com.mapk.fastkfunction.spreadwrapper.ForKFunction
77
import com.mapk.fastkfunction.spreadwrapper.ForMethod
8+
import org.jetbrains.annotations.TestOnly
89
import java.lang.reflect.Method
910
import java.lang.reflect.Modifier
1011
import kotlin.reflect.KFunction
@@ -129,47 +130,49 @@ sealed class FastKFunction<T> {
129130
}
130131

131132
companion object {
132-
private fun List<KParameter>.checkParameters() = also {
133-
val requireInstanceParameter = this[0].kind != KParameter.Kind.VALUE
134-
135-
if (isEmpty() || (requireInstanceParameter && size == 1))
133+
@TestOnly
134+
internal fun List<KParameter>.checkParameters() = also {
135+
if (isEmpty() || (this[0].kind != KParameter.Kind.VALUE && size == 1))
136136
throw IllegalArgumentException("This function is not require arguments.")
137137

138-
if (3 <= size && requireInstanceParameter && get(1).kind != KParameter.Kind.VALUE)
138+
if (2 <= size && this[1].kind != KParameter.Kind.VALUE)
139139
throw IllegalArgumentException("This function is require multiple instances.")
140140
}
141141

142-
private fun <T> topLevelFunctionOf(
142+
@TestOnly
143+
internal fun <T> topLevelFunctionOf(
143144
function: KFunction<T>,
144145
instance: Any?,
145146
parameters: List<KParameter>,
146147
method: Method
147148
): FastKFunction<T> = when {
148149
// KParameter.Kind.EXTENSION_RECEIVERの要求が有れば確定で拡張関数
149-
parameters[0].kind == KParameter.Kind.EXTENSION_RECEIVER -> {
150+
parameters[0].kind == KParameter.Kind.EXTENSION_RECEIVER ->
150151
// 対象が拡張関数ならinstanceはreceiver、指定が無ければエラー
151-
instance ?: throw IllegalArgumentException(
152-
"Function requires EXTENSION_RECEIVER instance, but is not present."
153-
)
152+
instance.instanceOrThrow(KParameter.Kind.EXTENSION_RECEIVER).let {
153+
checkInstanceClass(parameters[0].clazz, it::class)
154154

155-
val generator = BucketGenerator(parameters, instance)
156-
val valueParameters = parameters.subList(1, parameters.size)
155+
val generator = BucketGenerator(parameters, it)
156+
val valueParameters = parameters.subList(1, parameters.size)
157157

158-
TopLevelExtensionFunction(function, method, instance, generator, valueParameters)
159-
}
158+
TopLevelExtensionFunction(function, method, it, generator, valueParameters)
159+
}
160160
// javaMethodのパラメータサイズとKFunctionのパラメータサイズが違う場合も拡張関数
161161
// インスタンスが設定されていれば高速呼び出し、そうじゃなければ通常の関数呼び出し
162162
method.parameters.size != parameters.size ->
163163
instance
164164
?.let {
165+
checkInstanceClass(method.parameters[0].type.kotlin, it::class)
166+
165167
// KFunctionとしては値パラメータを求めていないため、バケツにはインスタンスを設定しない
166168
TopLevelExtensionFunction(function, method, it, BucketGenerator(parameters, null), parameters)
167169
} ?: Function(function, parameters)
168170
// トップレベル関数
169171
else -> TopLevelFunction(function, method, parameters)
170172
}
171173

172-
private fun <T> instanceFunctionOf(
174+
@TestOnly
175+
internal fun <T> instanceFunctionOf(
173176
function: KFunction<T>,
174177
inputtedInstance: Any?,
175178
parameters: List<KParameter>,
@@ -178,15 +181,21 @@ sealed class FastKFunction<T> {
178181
val instance = inputtedInstance ?: method.declaringObject
179182

180183
return if (parameters[0].kind == KParameter.Kind.INSTANCE) {
181-
instance ?: throw IllegalArgumentException("Function requires INSTANCE parameter, but is not present.")
184+
instance.instanceOrThrow(KParameter.Kind.INSTANCE).let { nonNullInstance ->
185+
checkInstanceClass(parameters[0].clazz, nonNullInstance::class)
182186

183-
val generator = BucketGenerator(parameters, instance)
184-
val valueParameters = parameters.subList(1, parameters.size)
187+
val generator = BucketGenerator(parameters, instance)
188+
val valueParameters = parameters.subList(1, parameters.size)
185189

186-
InstanceFunction(function, method, instance, generator, valueParameters)
190+
InstanceFunction(function, method, nonNullInstance, generator, valueParameters)
191+
}
187192
} else {
188193
instance
189-
?.let { InstanceFunction(function, method, it, BucketGenerator(parameters, null), parameters) }
194+
?.let {
195+
checkInstanceClass(method.declaringClass.kotlin, it::class)
196+
197+
InstanceFunction(function, method, it, BucketGenerator(parameters, null), parameters)
198+
}
190199
?: Function(function, parameters)
191200
}
192201
}

src/main/kotlin/com/mapk/fastkfunction/InternalFunctions.kt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package com.mapk.fastkfunction
22

33
import java.lang.reflect.Method
4+
import kotlin.reflect.KClass
5+
import kotlin.reflect.KParameter
6+
import kotlin.reflect.full.isSuperclassOf
47

58
/**
69
* Get object instance if receiver declared in object.
@@ -10,3 +13,36 @@ import java.lang.reflect.Method
1013
* @throws UnsupportedOperationException Method declared on top level.
1114
*/
1215
internal val Method.declaringObject: Any? get() = declaringClass.kotlin.objectInstance
16+
17+
/**
18+
* Get KParameters KClass.
19+
*
20+
* @receiver KParameter.
21+
* @returns KClass.
22+
*/
23+
internal val KParameter.clazz: KClass<*> get() = this.type.classifier as KClass<*>
24+
25+
/**
26+
* Check instance class is valid.
27+
*
28+
* @param expected Required clazz.
29+
* @param actual Actual clazz.
30+
* @throws IllegalArgumentException If actual is not required class.
31+
*/
32+
internal fun checkInstanceClass(expected: KClass<*>, actual: KClass<*>) {
33+
if (!expected.isSuperclassOf(actual))
34+
throw IllegalArgumentException(
35+
"INSTANCE parameter required ${expected.simpleName}, but ${actual.simpleName} is present."
36+
)
37+
}
38+
39+
/**
40+
* Throw IllegalArgumentException if instance is null.
41+
*
42+
* @receiver Instance parameter.
43+
* @param kind Instance Kind.
44+
* @return instance.
45+
* @throws IllegalArgumentException Instance is null.
46+
*/
47+
internal fun <T : Any> T?.instanceOrThrow(kind: KParameter.Kind): T =
48+
this ?: throw IllegalArgumentException("Function requires ${kind.name} parameter, but is not present.")

src/main/kotlin/com/mapk/fastkfunction/SingleArgFastKFunction.kt

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.mapk.fastkfunction
22

3+
import org.jetbrains.annotations.TestOnly
34
import java.lang.reflect.Method
45
import java.lang.reflect.Modifier
56
import kotlin.reflect.KFunction
@@ -54,42 +55,51 @@ sealed class SingleArgFastKFunction<T> {
5455
}
5556

5657
companion object {
57-
private fun List<KParameter>.checkParameters() = also {
58-
val requireInstanceParameter = this[0].kind != KParameter.Kind.VALUE
58+
@TestOnly
59+
internal fun List<KParameter>.checkParameters() = also {
60+
val requireInstanceParameter = !isEmpty() && this[0].kind != KParameter.Kind.VALUE
5961

6062
if (isEmpty() || (requireInstanceParameter && size == 1))
6163
throw IllegalArgumentException("This function is not require arguments.")
6264

6365
if (!(this.size == 1 || (this.size == 2 && requireInstanceParameter)))
6466
throw IllegalArgumentException("This function is require multiple arguments.")
67+
68+
if (this.size == 2 && this[1].kind != KParameter.Kind.VALUE)
69+
throw IllegalArgumentException("This function is require multiple instances.")
6570
}
6671

67-
private fun <T> topLevelFunctionOf(
72+
@TestOnly
73+
internal fun <T> topLevelFunctionOf(
6874
function: KFunction<T>,
6975
instance: Any?,
7076
parameters: List<KParameter>,
7177
method: Method
7278
): SingleArgFastKFunction<T> = when {
7379
// KParameter.Kind.EXTENSION_RECEIVERの要求が有れば確定で拡張関数
74-
parameters[0].kind == KParameter.Kind.EXTENSION_RECEIVER -> {
80+
parameters[0].kind == KParameter.Kind.EXTENSION_RECEIVER ->
7581
// 対象が拡張関数ならinstanceはreceiver、指定が無ければエラー
76-
instance ?: throw IllegalArgumentException(
77-
"Function requires EXTENSION_RECEIVER instance, but is not present."
78-
)
82+
instance.instanceOrThrow(KParameter.Kind.EXTENSION_RECEIVER).let {
83+
checkInstanceClass(parameters[0].clazz, it::class)
7984

80-
TopLevelExtensionFunction(parameters[1], method, instance)
81-
}
85+
TopLevelExtensionFunction(parameters[1], method, it)
86+
}
8287
// javaMethodのパラメータサイズとKFunctionのパラメータサイズが違う場合も拡張関数
8388
// インスタンスが設定されていれば高速呼び出し、そうじゃなければ通常の関数呼び出し
8489
method.parameters.size != parameters.size ->
8590
instance
86-
?.let { TopLevelExtensionFunction(parameters[0], method, instance) }
91+
?.let {
92+
checkInstanceClass(method.parameters[0].type.kotlin, it::class)
93+
94+
TopLevelExtensionFunction(parameters[0], method, instance)
95+
}
8796
?: Function(parameters[0], function)
8897
// トップレベル関数
8998
else -> TopLevelFunction(parameters[0], method)
9099
}
91100

92-
private fun <T> instanceFunctionOf(
101+
@TestOnly
102+
internal fun <T> instanceFunctionOf(
93103
function: KFunction<T>,
94104
inputtedInstance: Any?,
95105
parameters: List<KParameter>,
@@ -99,10 +109,16 @@ sealed class SingleArgFastKFunction<T> {
99109

100110
return when {
101111
parameters[0].kind == KParameter.Kind.INSTANCE ->
102-
instance
103-
?.let { InstanceFunction(parameters[1], method, it) }
104-
?: throw IllegalArgumentException("Function requires INSTANCE parameter, but is not present.")
105-
instance != null -> InstanceFunction(parameters[0], method, instance)
112+
instance.instanceOrThrow(KParameter.Kind.INSTANCE).let {
113+
checkInstanceClass(method.declaringClass.kotlin, it::class)
114+
115+
InstanceFunction(parameters[1], method, it)
116+
}
117+
instance != null -> {
118+
checkInstanceClass(method.declaringClass.kotlin, instance::class)
119+
120+
InstanceFunction(parameters[0], method, instance)
121+
}
106122
else -> Function(parameters[0], function)
107123
}
108124
}

0 commit comments

Comments
 (0)