Skip to content

Commit d105874

Browse files
authored
Merge pull request #130 from lupuuss/kotlin-2.3.20
Kotlin 2.3.20
2 parents 9aa6b02 + 02453b9 commit d105874

File tree

138 files changed

+873
-174
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

138 files changed

+873
-174
lines changed

gradle/libs.versions.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
[versions]
2-
kotlinMininumSupported="2.3.0"
3-
kotlin = "2.3.10"
2+
kotlinMininumSupported = "2.3.0"
3+
kotlin = "2.3.20-RC"
44
kotlinx-coroutines = "1.10.2"
55
buildconfig = "5.7.0"
66
google-autoservice = "1.1.1"
77
atomicfu = "0.31.0"
88
dokka = "2.1.0"
9-
poko = "0.20.2"
9+
poko = "0.21.1"
1010
vanniktech-publish-plugin = "0.36.0"
1111
gradle-portal-publish = "2.0.0"
1212

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package dev.mokkery.plugin.fir.compat
2+
3+
import org.jetbrains.kotlin.descriptors.runtime.components.tryLoadClass
4+
import org.jetbrains.kotlin.fir.FirElement
5+
import org.jetbrains.kotlin.fir.declarations.FirFunction
6+
7+
fun FirFunction.isNamedFunctionCompat(): Boolean {
8+
if (firNamedFunctionClass != null) return firNamedFunctionClass.isInstance(this)
9+
return requireNotNull(firSimpleFunctionClass) { "Incompatible Kotlin compiler version detected!" }.isInstance(this)
10+
}
11+
12+
fun FirElement.isSimpleFunctionCompat(): Boolean = firSimpleFunctionClass?.isInstance(this) ?: false
13+
14+
private val firNamedFunctionClass = Unit::class.java
15+
.classLoader
16+
.tryLoadClass("org.jetbrains.kotlin.fir.declarations.FirNamedFunction")
17+
18+
private val firSimpleFunctionClass = Unit::class.java
19+
.classLoader
20+
.tryLoadClass("org.jetbrains.kotlin.fir.declarations.FirSimpleFunction")

mokkery-plugin/src/main/kotlin/dev/mokkery/plugin/fir/diagnostics/MatchersDeclarationChecker.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package dev.mokkery.plugin.fir.diagnostics
22

33
import dev.mokkery.plugin.Mokkery
44
import dev.mokkery.plugin.fir.acceptsMatcher
5+
import dev.mokkery.plugin.fir.compat.isNamedFunctionCompat
56
import dev.mokkery.plugin.fir.getMatcherAnnotation
67
import dev.mokkery.plugin.fir.isMatcher
78
import dev.mokkery.plugin.fir.isMokkeryMatcherScope
@@ -17,7 +18,6 @@ import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind
1718
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
1819
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirFunctionChecker
1920
import org.jetbrains.kotlin.fir.declarations.FirFunction
20-
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
2121
import org.jetbrains.kotlin.fir.declarations.utils.isExternal
2222
import org.jetbrains.kotlin.fir.declarations.utils.modality
2323
import org.jetbrains.kotlin.fir.resolve.defaultType
@@ -67,7 +67,7 @@ class MatchersDeclarationChecker(
6767

6868
context(context: CheckerContext, reporter: DiagnosticReporter)
6969
private fun checkOrigin(declaration: FirFunction) {
70-
if (declaration !is FirSimpleFunction) {
70+
if (!declaration.isNamedFunctionCompat()) {
7171
reporter.reportOn(declaration.source, Diagnostics.MATCHER_MUST_BE_REGULAR_FUNCTION)
7272
}
7373
}

mokkery-plugin/src/main/kotlin/dev/mokkery/plugin/fir/diagnostics/MatchersUsageReporterVisitor.kt

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package dev.mokkery.plugin.fir.diagnostics
33
import dev.mokkery.plugin.Mokkery.Callable
44
import dev.mokkery.plugin.fir.acceptsMatcher
55
import dev.mokkery.plugin.fir.allNonDispatchArgumentsMapping
6+
import dev.mokkery.plugin.fir.compat.isSimpleFunctionCompat
67
import dev.mokkery.plugin.fir.extractArrayLiteralCall
78
import dev.mokkery.plugin.fir.isSpread
89
import org.jetbrains.kotlin.config.CompilerConfiguration
@@ -20,7 +21,7 @@ import org.jetbrains.kotlin.fir.declarations.FirClass
2021
import org.jetbrains.kotlin.fir.declarations.FirFunction
2122
import org.jetbrains.kotlin.fir.declarations.FirProperty
2223
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
23-
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
24+
import org.jetbrains.kotlin.fir.declarations.FirNamedFunction
2425
import org.jetbrains.kotlin.fir.declarations.utils.isFinal
2526
import org.jetbrains.kotlin.fir.expressions.FirBooleanOperatorExpression
2627
import org.jetbrains.kotlin.fir.expressions.FirDoWhileLoop
@@ -86,11 +87,15 @@ class MatchersUsageReporterVisitor(
8687
private val callAssociatedLambdas = mutableMapOf<FirFunctionSymbol<*>, FirFunctionCall?>()
8788
private val legalizedNonMemberFunctionWithMatchers = mutableSetOf<FirFunctionCall>()
8889

89-
override fun visitElement(element: FirElement) = element.acceptChildren(this)
90+
override fun visitElement(element: FirElement) {
91+
// backward compat - cannot override removed type so it's handled here
92+
if (element is FirFunction && element.isSimpleFunctionCompat()) return visitFunction(element)
93+
element.acceptChildren(this)
94+
}
9095

9196
override fun visitAnonymousObject(anonymousObject: FirAnonymousObject) {
9297
nestedClassStack.add(anonymousObject.symbol)
93-
super.visitAnonymousObject(anonymousObject)
98+
anonymousObject.acceptChildren(this)
9499
nestedClassStack.popLast()
95100
}
96101

@@ -100,40 +105,40 @@ class MatchersUsageReporterVisitor(
100105

101106
override fun visitClass(klass: FirClass) {
102107
nestedClassStack.add(klass.symbol)
103-
super.visitClass(klass)
108+
klass.acceptChildren(this)
104109
nestedClassStack.popLast()
105110
}
106111

107112
override fun visitAnonymousFunction(anonymousFunction: FirAnonymousFunction) {
108113
functionsStack += anonymousFunction.symbol
109114
callAssociatedLambdas[anonymousFunction.symbol] = currentCallsStack.lastOrNull()
110-
super.visitAnonymousFunction(anonymousFunction)
115+
anonymousFunction.acceptChildren(this)
111116
callAssociatedLambdas.remove(anonymousFunction.symbol)
112117
functionsStack -= anonymousFunction.symbol
113118
}
114119

115-
override fun visitSimpleFunction(simpleFunction: FirSimpleFunction) {
116-
visitFunction(simpleFunction)
120+
override fun visitNamedFunction(namedFunction: FirNamedFunction) {
121+
visitFunction(namedFunction)
117122
}
118123

119124
override fun visitFunction(function: FirFunction) {
120125
functionsStack += function.symbol
121-
super.visitFunction(function)
126+
function.acceptChildren(this)
122127
functionsStack -= function.symbol
123128
}
124129

125130
override fun visitProperty(property: FirProperty) {
126131
matchersProcessor.processVariable(property)
127-
super.visitProperty(property)
132+
property.acceptChildren(this)
128133
}
129134

130135
override fun visitVariableAssignment(variableAssignment: FirVariableAssignment) = context(context) {
131136
val variableSymbol = variableAssignment
132137
.calleeReference
133138
?.toResolvedVariableSymbol()
134-
?: return@context super.visitVariableAssignment(variableAssignment)
135-
if (variableAssignment.dispatchReceiver != null) return@context super.visitVariableAssignment(variableAssignment)
136-
if (!matchersProcessor.isMatcher(variableAssignment.rValue)) return@context super.visitVariableAssignment(variableAssignment)
139+
?: return@context variableAssignment.acceptChildren(this)
140+
if (variableAssignment.dispatchReceiver != null) return@context variableAssignment.acceptChildren(this)
141+
if (!matchersProcessor.isMatcher(variableAssignment.rValue)) return@context variableAssignment.acceptChildren(this)
137142
when (matchersProcessor.getResultFor(variableSymbol)) {
138143
null -> reporter.reportOn(
139144
source = variableAssignment.source,
@@ -147,7 +152,7 @@ class MatchersUsageReporterVisitor(
147152
)
148153
else -> Unit
149154
}
150-
return@context super.visitVariableAssignment(variableAssignment)
155+
return@context variableAssignment.acceptChildren(this)
151156
}
152157

153158
override fun visitWhenExpression(whenExpression: FirWhenExpression) = context(context) {
@@ -161,11 +166,12 @@ class MatchersUsageReporterVisitor(
161166
.forEachMatcher {
162167
reporter.reportOn(it.source, Diagnostics.ILLEGAL_MATCHER_IN_CONDITION)
163168
}
164-
super.visitWhenExpression(whenExpression)
169+
whenExpression.acceptChildren(this)
165170
}
166171

167172
override fun visitWhileLoop(whileLoop: FirWhileLoop) {
168-
visitLoop(whileLoop) }
173+
visitLoop(whileLoop)
174+
}
169175

170176
override fun visitDoWhileLoop(doWhileLoop: FirDoWhileLoop) {
171177
visitLoop(doWhileLoop)
@@ -175,7 +181,7 @@ class MatchersUsageReporterVisitor(
175181
if (matchersProcessor.isMatcher(loop.condition)) {
176182
reporter.reportOn(loop.condition.source, Diagnostics.ILLEGAL_MATCHER_IN_CONDITION)
177183
}
178-
super.visitLoop(loop)
184+
loop.acceptChildren(this)
179185
}
180186

181187
override fun visitTypeOperatorCall(typeOperatorCall: FirTypeOperatorCall) = context(context) {
@@ -184,7 +190,7 @@ class MatchersUsageReporterVisitor(
184190
reporter.reportOn(it.source, Diagnostics.ILLEGAL_OPERATOR_USAGE, typeOperatorCall.operation.operator)
185191
}
186192
}
187-
super.visitTypeOperatorCall(typeOperatorCall)
193+
typeOperatorCall.acceptChildren(this)
188194
}
189195

190196
override fun visitEqualityOperatorCall(equalityOperatorCall: FirEqualityOperatorCall) = context(context) {
@@ -197,7 +203,7 @@ class MatchersUsageReporterVisitor(
197203
)
198204
}
199205
}
200-
super.visitEqualityOperatorCall(equalityOperatorCall)
206+
equalityOperatorCall.acceptChildren(this)
201207
}
202208

203209
override fun visitBooleanOperatorExpression(
@@ -208,7 +214,7 @@ class MatchersUsageReporterVisitor(
208214
reporter.reportOn(it.source, Diagnostics.ILLEGAL_OPERATOR_USAGE, booleanOperatorExpression.kind.token)
209215
}
210216
}
211-
super.visitBooleanOperatorExpression(booleanOperatorExpression)
217+
booleanOperatorExpression.acceptChildren(this)
212218
}
213219

214220
override fun visitTryExpression(tryExpression: FirTryExpression) = context(context) {
@@ -223,24 +229,24 @@ class MatchersUsageReporterVisitor(
223229
if (matchersProcessor.isMatcher(tryExpression.finallyBlock?.lastExpression)) {
224230
reporter.reportOn(tryExpression.source, Diagnostics.ILLEGAL_TRY_CATCH)
225231
}
226-
super.visitTryExpression(tryExpression)
232+
tryExpression.acceptChildren(this)
227233
}
228234

229235
override fun visitGetClassCall(getClassCall: FirGetClassCall) = context(context) {
230236
if (matchersProcessor.isMatcher(getClassCall.argument)) {
231237
reporter.reportOn(getClassCall.argument.source, Diagnostics.ILLEGAL_OPERATOR_USAGE, "::class")
232238
}
233-
super.visitGetClassCall(getClassCall)
239+
getClassCall.acceptChildren(this)
234240
}
235241

236242
override fun visitFunctionCall(functionCall: FirFunctionCall): Unit = context(context) {
237243
val callee = functionCall.calleeReference as? FirResolvedNamedReference
238-
?: return super.visitFunctionCall(functionCall)
244+
?: return functionCall.acceptChildren(this)
239245
val symbol = callee.resolvedSymbol as? FirFunctionSymbol<*>
240-
?: return super.visitFunctionCall(functionCall)
246+
?: return functionCall.acceptChildren(this)
241247
if (symbol.callableId in templatingFunctions) {
242248
reporter.reportOn(functionCall.source, Diagnostics.ILLEGAL_NESTED_TEMPLATING, symbol.name)
243-
return super.visitFunctionCall(functionCall)
249+
return functionCall.acceptChildren(this)
244250
}
245251
val dispatchReceiver = functionCall.dispatchReceiver
246252
when {
@@ -258,7 +264,7 @@ class MatchersUsageReporterVisitor(
258264
}
259265
}
260266
currentCallsStack.add(functionCall)
261-
super.visitFunctionCall(functionCall)
267+
functionCall.acceptChildren(this)
262268
currentCallsStack.removeLast()
263269
}
264270

mokkery-plugin/src/main/kotlin/dev/mokkery/plugin/ir/IrBuilder.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package dev.mokkery.plugin.ir
22

3+
import dev.mokkery.plugin.ir.compat.LOCAL_FUNCTION_FOR_LAMBDA_COMPAT
34
import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder
45
import org.jetbrains.kotlin.backend.common.lower.irIfThen
56
import org.jetbrains.kotlin.backend.common.lower.irNot
@@ -99,7 +100,7 @@ fun IrBuilderWithScope.irLambdaOf(
99100
this.returnType = returnType
100101
this.isSuspend = lambdaType.isSuspendFunction()
101102
visibility = DescriptorVisibilities.LOCAL
102-
origin = IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA
103+
origin = IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA_COMPAT
103104
}.apply {
104105
val bodyBuilder = DeclarationIrBuilder(context, symbol, startOffset, endOffset)
105106
params.forEachIndexed { i, it ->

mokkery-plugin/src/main/kotlin/dev/mokkery/plugin/ir/IrClass.kt

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ package dev.mokkery.plugin.ir
22

33
import dev.mokkery.plugin.ir.annotations.AnnotationFilter
44
import dev.mokkery.plugin.ir.annotations.deepApplyAnnotationsFilter
5+
import dev.mokkery.plugin.ir.compat.DEFAULT_PROPERTY_ACCESSOR_COMPAT
6+
import dev.mokkery.plugin.ir.compat.DEFINED_COMPAT
7+
import dev.mokkery.plugin.ir.compat.addBackingFieldCompat
58
import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder
69
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
710
import org.jetbrains.kotlin.descriptors.Modality
@@ -95,7 +98,7 @@ fun IrClass.addOverridingMethod(
9598
updateFrom(function)
9699
name = function.name
97100
modality = Modality.FINAL
98-
origin = IrDeclarationOrigin.DEFINED
101+
origin = IrDeclarationOrigin.DEFINED_COMPAT
99102
isFakeOverride = false
100103
}.apply {
101104
overriddenSymbols = function.overriddenSymbols + functions.map(IrSimpleFunction::symbol)
@@ -179,7 +182,7 @@ fun IrClass.addOverridingProperty(
179182
updateFrom(property)
180183
name = property.name
181184
modality = Modality.FINAL
182-
origin = IrDeclarationOrigin.DEFINED
185+
origin = IrDeclarationOrigin.DEFINED_COMPAT
183186
isFakeOverride = false
184187
}.apply {
185188
overriddenSymbols = property.overriddenSymbols + properties.map(IrProperty::symbol)
@@ -219,17 +222,17 @@ fun IrClass.overridePropertyBackingField(context: IrGeneratorContext, property:
219222
name = property.name
220223
isVar = property.isVar
221224
modality = Modality.FINAL
222-
origin = IrDeclarationOrigin.DEFINED
225+
origin = IrDeclarationOrigin.DEFINED_COMPAT
223226
}.apply {
224227
val returnType = property.getter!!.returnType
225-
addBackingField {
228+
addBackingFieldCompat {
226229
type = returnType
227230
visibility = DescriptorVisibilities.PRIVATE
228231
}
229232
overriddenSymbols = listOf(property.symbol)
230233
addGetter {
231234
this.returnType = returnType
232-
origin = IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR
235+
origin = IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR_COMPAT
233236
}.apply {
234237
parameters = listOf(createDispatchReceiverParameterWithClassParent())
235238
body = DeclarationIrBuilder(context, symbol).irBlockBody {
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package dev.mokkery.plugin.ir.compat
2+
3+
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
4+
import org.jetbrains.kotlin.ir.builders.declarations.IrFieldBuilder
5+
import org.jetbrains.kotlin.ir.builders.declarations.buildField
6+
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
7+
import org.jetbrains.kotlin.ir.declarations.IrField
8+
import org.jetbrains.kotlin.ir.declarations.IrProperty
9+
10+
fun IrProperty.addBackingFieldCompat(builder: IrFieldBuilder.() -> Unit): IrField {
11+
return factory.buildField {
12+
name = this@addBackingFieldCompat.name
13+
origin = IrDeclarationOrigin.PROPERTY_BACKING_FIELD_COMPAT
14+
visibility = DescriptorVisibilities.PRIVATE
15+
builder()
16+
}.also { field ->
17+
this@addBackingFieldCompat.backingField = field
18+
field.correspondingPropertySymbol = this@addBackingFieldCompat.symbol
19+
field.parent = this@addBackingFieldCompat.parent
20+
}
21+
}
22+
23+
val IrDeclarationOrigin.Companion.LOCAL_FUNCTION_FOR_LAMBDA_COMPAT: IrDeclarationOrigin
24+
get() = try {
25+
IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA
26+
} catch (_: NoSuchMethodError) {
27+
LOCAL_FUNCTION_FOR_LAMBDA_OLD
28+
}
29+
30+
val IrDeclarationOrigin.Companion.PROPERTY_BACKING_FIELD_COMPAT: IrDeclarationOrigin
31+
get() = try {
32+
IrDeclarationOrigin.PROPERTY_BACKING_FIELD
33+
} catch (_: NoSuchMethodError) {
34+
PROPERTY_BACKING_FIELD_OLD
35+
}
36+
37+
val IrDeclarationOrigin.Companion.DEFAULT_PROPERTY_ACCESSOR_COMPAT: IrDeclarationOrigin
38+
get() = try {
39+
IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR
40+
} catch (_: NoSuchMethodError) {
41+
DEFAULT_PROPERTY_ACCESSOR_OLD
42+
}
43+
44+
val IrDeclarationOrigin.Companion.DEFINED_COMPAT: IrDeclarationOrigin
45+
get() = try {
46+
IrDeclarationOrigin.DEFINED
47+
} catch (_: NoSuchMethodError) {
48+
DEFINED_OLD
49+
}
50+
51+
private val DEFINED_OLD: IrDeclarationOrigin by lazy {
52+
IrDeclarationOrigin.Companion::class.java
53+
.methods
54+
.first { it.name == "getDEFINED" }
55+
.invoke(IrDeclarationOrigin.Companion) as IrDeclarationOrigin
56+
}
57+
58+
private val LOCAL_FUNCTION_FOR_LAMBDA_OLD: IrDeclarationOrigin by lazy {
59+
IrDeclarationOrigin.Companion::class.java
60+
.methods
61+
.first { it.name == "getLOCAL_FUNCTION_FOR_LAMBDA" }
62+
.invoke(IrDeclarationOrigin.Companion) as IrDeclarationOrigin
63+
}
64+
65+
private val DEFAULT_PROPERTY_ACCESSOR_OLD: IrDeclarationOrigin by lazy {
66+
IrDeclarationOrigin.Companion::class.java
67+
.methods
68+
.first { it.name == "getDEFAULT_PROPERTY_ACCESSOR" }
69+
.invoke(IrDeclarationOrigin.Companion) as IrDeclarationOrigin
70+
}
71+
72+
private val PROPERTY_BACKING_FIELD_OLD: IrDeclarationOrigin by lazy {
73+
IrDeclarationOrigin.Companion::class.java
74+
.methods
75+
.first { it.name == "getPROPERTY_BACKING_FIELD" }
76+
.invoke(IrDeclarationOrigin.Companion) as IrDeclarationOrigin
77+
}

0 commit comments

Comments
 (0)