[PL] Deep rework of the partial linkage
1. Leaving no unbound symbols in the IR tree, KT-54491:
- All unbound symbols are bound to synthetic stub declarations
- Improved detection of the root cause for every partially linked classifier
- Improved error messages
2. Visibility valiation, KT-54469
3. Always check deserialized symbols:
If the deserialized symbol mismatches the symbol kind at the call site in the deserializer then generate and reference another symbol with the same signature. In case PL is off, just throw IrSymbolTypeMismatchException.
4. Handle class inheritance violation:
- Detect illegal inheritance (ex: inheriting from a final class)
- Detect invalid constructor delegation (ex: delegating to another class than the direct superclass)
- Simplification: Reduce the number of PartialLinkageCase subclasses
- Reworked error message generation to have shorter and clearer messages
5. Handle class transformations and all known side-effects, examples:
- nested <-> inner
- class <-> enum/object
- adding/removing subclasses of sealed class
- adding/removing enum entries
6. Check direct instantiation of abstract class.
Such instantiation could be possible if a class was non-abstract in the previous version of a library.
7. Handle unlinked annotations on declarations.
Such annotations are removed from the IR. The appropriate compiler error message is produced for every individual case.
8. Handle value argument count mismatch at call sites
9. Handle calling suspend function from non-suspend context.
This could happen if a suspen function was non-suspend in the previous version of a library.
10. Handle overriding inline callables.
Only the leaf final callable can be marked with `inline`.
11. Detect illegal non-local returns from noinline/crossinline lambdas.
This commit is contained in:
committed by
Space Team
parent
974ee3139c
commit
2a4d880037
@@ -92,6 +92,8 @@ interface IrStatementOrigin {
|
||||
|
||||
object SYNTHETIC_NOT_AUTOBOXED_CHECK : IrStatementOriginImpl("SYNTHETIC_NOT_AUTOBOXED_CHECK")
|
||||
|
||||
object PARTIAL_LINKAGE_RUNTIME_ERROR : IrStatementOriginImpl("PARTIAL_LINKAGE_RUNTIME_ERROR")
|
||||
|
||||
data class COMPONENT_N private constructor(val index: Int) : IrStatementOriginImpl("COMPONENT_$index") {
|
||||
companion object {
|
||||
private val precreatedComponents = Array(32) { i -> COMPONENT_N(i + 1) }
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.linkage.partial
|
||||
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
* Describes the reason why a certain classifier is considered as unusable (partially linked).
|
||||
* For more details see [ClassifierExplorer.exploreSymbol].
|
||||
*/
|
||||
@Suppress("KDocUnresolvedReference")
|
||||
sealed interface ExploredClassifier {
|
||||
/** Indicated unusable classifier. */
|
||||
sealed interface Unusable : ExploredClassifier {
|
||||
val symbol: IrClassifierSymbol
|
||||
|
||||
sealed interface CanBeRootCause : Unusable
|
||||
|
||||
/**
|
||||
* There is no real owner classifier for the symbol, only synthetic stub created by [MissingDeclarationStubGenerator].
|
||||
* Likely the classifier has been deleted in newer version of the library.
|
||||
*/
|
||||
data class MissingClassifier(override val symbol: IrClassifierSymbol) : CanBeRootCause
|
||||
|
||||
/**
|
||||
* There is an issue with inheritance: interface inherits from a class, class inherits from a final class, etc.
|
||||
* On practice, such class can't be instantiated and used anywhere.
|
||||
*/
|
||||
class InvalidInheritance(override val symbol: IrClassSymbol, val superClassSymbols: Collection<IrClassSymbol>) : CanBeRootCause {
|
||||
init {
|
||||
// Just a sanity check to avoid creating invalid [InvalidInheritance]s.
|
||||
check(superClassSymbols.isNotEmpty())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The annotation class has unacceptable classifier as one of its parameters: not one of permitted classes ([String], [KClass]),
|
||||
* primitives, etc. This may happen if the class representing this parameter was an annotation class before, but later it was
|
||||
* converted to a non-annotation class.
|
||||
*/
|
||||
data class AnnotationWithUnacceptableParameter(
|
||||
override val symbol: IrClassSymbol,
|
||||
val unacceptableClassifierSymbol: IrClassifierSymbol
|
||||
) : CanBeRootCause
|
||||
|
||||
/**
|
||||
* The classifier depends on another unusable classifier. Thus, it is considered unusable too.
|
||||
*/
|
||||
data class DueToOtherClassifier(override val symbol: IrClassifierSymbol, val rootCause: CanBeRootCause) : Unusable
|
||||
}
|
||||
|
||||
/** Indicates usable (fully linked) classifier. */
|
||||
object Usable : ExploredClassifier
|
||||
}
|
||||
+3
-3
@@ -3,7 +3,7 @@
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.overrides
|
||||
package org.jetbrains.kotlin.ir.linkage.partial
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
@@ -11,9 +11,9 @@ import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrOverridableMember
|
||||
|
||||
interface IrUnimplementedOverridesStrategy {
|
||||
class Customization(val origin: IrDeclarationOrigin?, val modality: Modality?, val needToCreateBody: Boolean) {
|
||||
class Customization(val origin: IrDeclarationOrigin?, val modality: Modality?) {
|
||||
companion object {
|
||||
val NO = Customization(null, null, false)
|
||||
val NO = Customization(null, null)
|
||||
}
|
||||
}
|
||||
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.linkage.partial
|
||||
|
||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrOverridableDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.linkage.partial.PartialLinkageUtils.Module as PLModule
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
|
||||
/**
|
||||
* Describes a reason why an [IrDeclaration] or an [IrExpression] is partially linked. Subclasses represent various causes of the p.l.
|
||||
*/
|
||||
@Suppress("KDocUnresolvedReference")
|
||||
sealed interface PartialLinkageCase {
|
||||
/**
|
||||
* Unusable (partially linked) classifier.
|
||||
*
|
||||
* Applicable to: Declarations (classifiers).
|
||||
*/
|
||||
class UnusableClassifier(val cause: ExploredClassifier.Unusable.CanBeRootCause) : PartialLinkageCase
|
||||
|
||||
/**
|
||||
* There is no real owner declaration for the symbol, only synthetic stub created by [MissingDeclarationStubGenerator].
|
||||
* Likely the declaration has been deleted in newer version of the library.
|
||||
*
|
||||
* Applicable to: Declarations.
|
||||
*/
|
||||
class MissingDeclaration(val missingDeclarationSymbol: IrSymbol) : PartialLinkageCase
|
||||
|
||||
/**
|
||||
* Declaration's signature uses an unusable (partially linked) classifier symbol.
|
||||
*
|
||||
* Applicable to: Declarations.
|
||||
*/
|
||||
class DeclarationWithUnusableClassifier(
|
||||
val declarationSymbol: IrSymbol,
|
||||
val cause: ExploredClassifier.Unusable
|
||||
) : PartialLinkageCase
|
||||
|
||||
/**
|
||||
* Expression uses an unusable (partially linked) classifier symbol.
|
||||
* Example: An [IrTypeOperatorCall] that casts an argument to a type with unlinked symbol.
|
||||
*
|
||||
* Applicable to: Expressions.
|
||||
*/
|
||||
class ExpressionWithUnusableClassifier(
|
||||
val expression: IrExpression,
|
||||
val cause: ExploredClassifier.Unusable
|
||||
) : PartialLinkageCase
|
||||
|
||||
/**
|
||||
* Expression references a missing IR declaration (IR declaration)
|
||||
* Example: An [IrCall] references unlinked [IrSimpleFunctionSymbol].
|
||||
*
|
||||
* Applicable to: Expressions.
|
||||
*/
|
||||
class ExpressionWithMissingDeclaration(
|
||||
val expression: IrExpression,
|
||||
val missingDeclarationSymbol: IrSymbol
|
||||
) : PartialLinkageCase
|
||||
|
||||
/**
|
||||
* Expression refers an IR declaration with a signature that uses an unusable (partially linked) classifier symbol.
|
||||
*
|
||||
* Applicable to: Expressions.
|
||||
*/
|
||||
class ExpressionHasDeclarationWithUnusableClassifier(
|
||||
val expression: IrExpression,
|
||||
val referencedDeclarationSymbol: IrSymbol,
|
||||
val cause: ExploredClassifier.Unusable
|
||||
) : PartialLinkageCase
|
||||
|
||||
/**
|
||||
* Expression refers an IR declaration with the wrong type.
|
||||
* Example: An [IrEnumConstructorCall] that refers an [IrConstructor] of a regular class.
|
||||
*
|
||||
* Applicable to: Expressions.
|
||||
*/
|
||||
class ExpressionHasWrongTypeOfDeclaration(
|
||||
val expression: IrExpression,
|
||||
val actualDeclarationSymbol: IrSymbol,
|
||||
val expectedDeclarationDescription: String
|
||||
) : PartialLinkageCase
|
||||
|
||||
/**
|
||||
* Expression that refers to an IR function has an excessive or a missing dispatch receiver parameter,
|
||||
* or the number of value arguments in expression does not match the number of value parameters in function
|
||||
* (which may happen, for example, is a default value for a value parameter was removed).
|
||||
*
|
||||
* Applicable to: Expressions.
|
||||
*/
|
||||
class MemberAccessExpressionArgumentsMismatch(
|
||||
val expression: IrMemberAccessExpression<IrFunctionSymbol>,
|
||||
val expressionHasDispatchReceiver: Boolean,
|
||||
val functionHasDispatchReceiver: Boolean,
|
||||
val expressionValueArgumentCount: Int,
|
||||
val functionValueParameterCount: Int
|
||||
) : PartialLinkageCase
|
||||
|
||||
/**
|
||||
* An [IrCall] of suspendable function at the place where no coroutine context is available.
|
||||
*
|
||||
* Applicable to: Expressions.
|
||||
*/
|
||||
class SuspendableFunctionCallWithoutCoroutineContext(val expression: IrCall) : PartialLinkageCase
|
||||
|
||||
/**
|
||||
* A non-local return in context where it is not expected.
|
||||
*
|
||||
* Applicable to: Expressions.
|
||||
*/
|
||||
class IllegalNonLocalReturn(val expression: IrReturn, val validReturnTargets: Set<IrReturnTargetSymbol>) : PartialLinkageCase
|
||||
|
||||
/**
|
||||
* Expression refers an IR declaration that is not accessible at the use site.
|
||||
* Example: An [IrCall] that refers a private [IrSimpleFunction] from another module.
|
||||
*
|
||||
* Applicable to: Expressions.
|
||||
*/
|
||||
class ExpressionHasInaccessibleDeclaration(
|
||||
val expression: IrExpression,
|
||||
val referencedDeclarationSymbol: IrSymbol,
|
||||
val declaringModule: PLModule,
|
||||
val useSiteModule: PLModule
|
||||
) : PartialLinkageCase
|
||||
|
||||
/**
|
||||
* An [IrConstructor] delegates call to [unexpectedSuperClassConstructorSymbol] while should delegate to
|
||||
* one of constructors of [superClassSymbol].
|
||||
*/
|
||||
class InvalidConstructorDelegation(
|
||||
val constructorSymbol: IrConstructorSymbol,
|
||||
val superClassSymbol: IrClassSymbol,
|
||||
val unexpectedSuperClassConstructorSymbol: IrConstructorSymbol
|
||||
) : PartialLinkageCase
|
||||
|
||||
/**
|
||||
* An attempt to instantiate an abstract class from outside its inheritance hierarchy.
|
||||
*/
|
||||
class AbstractClassInstantiation(val constructorCall: IrConstructorCall, val classSymbol: IrClassSymbol) : PartialLinkageCase
|
||||
|
||||
/**
|
||||
* Unimplemented abstract callable member in non-abstract class.
|
||||
*
|
||||
* Applicable to: Declarations (functions, properties).
|
||||
*/
|
||||
class UnimplementedAbstractCallable(val callable: IrOverridableDeclaration<*>) : PartialLinkageCase
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.linkage.partial
|
||||
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.linkage.partial.PartialLinkageUtils.File as PLFile
|
||||
|
||||
interface PartialLinkageSupportForLowerings {
|
||||
val isEnabled: Boolean
|
||||
|
||||
fun throwLinkageError(
|
||||
partialLinkageCase: PartialLinkageCase,
|
||||
element: IrElement,
|
||||
file: PLFile,
|
||||
suppressWarningInCompilerOutput: Boolean
|
||||
): IrCall
|
||||
|
||||
companion object {
|
||||
val DISABLED = object : PartialLinkageSupportForLowerings {
|
||||
override val isEnabled get() = false
|
||||
override fun throwLinkageError(
|
||||
partialLinkageCase: PartialLinkageCase,
|
||||
element: IrElement,
|
||||
file: PLFile,
|
||||
suppressWarningInCompilerOutput: Boolean
|
||||
): IrCall = error("Should not be called")
|
||||
}
|
||||
}
|
||||
}
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.linkage.partial
|
||||
|
||||
import org.jetbrains.kotlin.builtins.FunctionInterfacePackageFragment
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.ir.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithName
|
||||
import org.jetbrains.kotlin.ir.declarations.IrExternalPackageFragment
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrContainerExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin.PARTIAL_LINKAGE_RUNTIME_ERROR
|
||||
import org.jetbrains.kotlin.ir.util.IrMessageLogger
|
||||
import org.jetbrains.kotlin.ir.util.getPackageFragment
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
fun IrStatement.isPartialLinkageRuntimeError(): Boolean {
|
||||
return when (this) {
|
||||
is IrCall -> origin == PARTIAL_LINKAGE_RUNTIME_ERROR //|| symbol == builtIns.linkageErrorSymbol
|
||||
is IrContainerExpression -> origin == PARTIAL_LINKAGE_RUNTIME_ERROR || statements.any { it.isPartialLinkageRuntimeError() }
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
object PartialLinkageUtils {
|
||||
/** For fast check if a declaration is in the module */
|
||||
sealed interface Module {
|
||||
val name: String
|
||||
|
||||
data class Real(override val name: String) : Module {
|
||||
constructor(name: Name) : this(name.asString())
|
||||
}
|
||||
|
||||
object SyntheticBuiltInFunctions : Module {
|
||||
override val name = "<synthetic built-in functions>"
|
||||
}
|
||||
|
||||
object MissingDeclarations : Module {
|
||||
override val name = "<missing declarations>"
|
||||
}
|
||||
|
||||
fun defaultLocationWithoutPath() = IrMessageLogger.Location(name, UNDEFINED_LINE_NUMBER, UNDEFINED_COLUMN_NUMBER)
|
||||
|
||||
companion object {
|
||||
fun determineModuleFor(declaration: IrDeclaration): Module = determineFor(
|
||||
declaration,
|
||||
onMissingDeclaration = MissingDeclarations,
|
||||
onSyntheticBuiltInFunction = SyntheticBuiltInFunctions,
|
||||
onIrBased = { Real(it.module.name) },
|
||||
onLazyIrBased = { Real(it.containingDeclaration.name) },
|
||||
onError = { error("Can't determine module for $declaration, name=${(declaration as? IrDeclarationWithName)?.name}") }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
sealed interface File {
|
||||
val module: Module
|
||||
fun computeLocationForOffset(offset: Int): IrMessageLogger.Location
|
||||
|
||||
data class IrBased(private val file: IrFile) : File {
|
||||
override val module = Module.Real(file.module.name)
|
||||
|
||||
override fun computeLocationForOffset(offset: Int): IrMessageLogger.Location {
|
||||
val lineNumber = if (offset == UNDEFINED_OFFSET) UNDEFINED_LINE_NUMBER else file.fileEntry.getLineNumber(offset) + 1 // since humans count from 1, not 0
|
||||
val columnNumber = if (offset == UNDEFINED_OFFSET) UNDEFINED_COLUMN_NUMBER else file.fileEntry.getColumnNumber(offset) + 1
|
||||
|
||||
// TODO: should module name still be added here?
|
||||
return IrMessageLogger.Location("${module.name} @ ${file.fileEntry.name}", lineNumber, columnNumber)
|
||||
}
|
||||
}
|
||||
|
||||
class LazyIrBased(packageFragmentDescriptor: PackageFragmentDescriptor) : File {
|
||||
override val module = Module.Real(packageFragmentDescriptor.containingDeclaration.name)
|
||||
private val defaultLocation = module.defaultLocationWithoutPath()
|
||||
|
||||
override fun equals(other: Any?) = (other as? LazyIrBased)?.module == module
|
||||
override fun hashCode() = module.hashCode()
|
||||
|
||||
override fun computeLocationForOffset(offset: Int) = defaultLocation
|
||||
}
|
||||
|
||||
object SyntheticBuiltInFunctions : File {
|
||||
override val module = Module.SyntheticBuiltInFunctions
|
||||
private val defaultLocation = module.defaultLocationWithoutPath()
|
||||
|
||||
override fun computeLocationForOffset(offset: Int) = defaultLocation
|
||||
}
|
||||
|
||||
object MissingDeclarations : File {
|
||||
override val module = Module.MissingDeclarations
|
||||
private val defaultLocation = module.defaultLocationWithoutPath()
|
||||
|
||||
override fun computeLocationForOffset(offset: Int) = defaultLocation
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun determineFileFor(declaration: IrDeclaration): File = determineFor(
|
||||
declaration,
|
||||
onMissingDeclaration = MissingDeclarations,
|
||||
onSyntheticBuiltInFunction = SyntheticBuiltInFunctions,
|
||||
onIrBased = ::IrBased,
|
||||
onLazyIrBased = ::LazyIrBased,
|
||||
onError = { error("Can't determine file for $declaration, name=${(declaration as? IrDeclarationWithName)?.name}") }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
private inline fun <R> determineFor(
|
||||
declaration: IrDeclaration,
|
||||
onMissingDeclaration: R,
|
||||
onSyntheticBuiltInFunction: R,
|
||||
onIrBased: (IrFile) -> R,
|
||||
onLazyIrBased: (PackageFragmentDescriptor) -> R,
|
||||
onError: () -> Nothing
|
||||
): R {
|
||||
return if (declaration.origin == PartiallyLinkedDeclarationOrigin.MISSING_DECLARATION)
|
||||
onMissingDeclaration
|
||||
else {
|
||||
val packageFragment = declaration.getPackageFragment()
|
||||
val packageFragmentDescriptor = with(packageFragment.symbol) { if (hasDescriptor) descriptor else null }
|
||||
|
||||
when {
|
||||
packageFragmentDescriptor is FunctionInterfacePackageFragment -> onSyntheticBuiltInFunction
|
||||
packageFragment is IrFile -> onIrBased(packageFragment)
|
||||
packageFragment is IrExternalPackageFragment && packageFragmentDescriptor != null -> onLazyIrBased(packageFragmentDescriptor)
|
||||
else -> onError()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.linkage.partial
|
||||
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
|
||||
@Suppress("KDocUnresolvedReference")
|
||||
enum class PartiallyLinkedDeclarationOrigin : IrDeclarationOrigin {
|
||||
/** The unresolved (missing) declaration */
|
||||
MISSING_DECLARATION,
|
||||
|
||||
/** The abstract callable member that needs to be implemented in non-abstract class */
|
||||
UNIMPLEMENTED_ABSTRACT_CALLABLE_MEMBER,
|
||||
|
||||
/** Auxiliary declaration generated by [PartiallyLinkedIrTreePatcher] */
|
||||
AUXILIARY_GENERATED_DECLARATION;
|
||||
}
|
||||
+1
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrOverridableMember
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.linkage.partial.IrUnimplementedOverridesStrategy
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.ir.overrides
|
||||
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.linkage.partial.IrUnimplementedOverridesStrategy
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
|
||||
class FakeOverrideCopier(
|
||||
@@ -62,10 +63,6 @@ class FakeOverrideCopier(
|
||||
extensionReceiverParameter = declaration.extensionReceiverParameter?.transform()
|
||||
returnType = typeRemapper.remapType(declaration.returnType)
|
||||
valueParameters = declaration.valueParameters.transform()
|
||||
|
||||
if (customization.needToCreateBody && body == null) {
|
||||
body = factory.createBlockBody(startOffset, endOffset)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,11 +8,12 @@ package org.jetbrains.kotlin.ir.overrides
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.linkage.partial.IrUnimplementedOverridesStrategy
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo
|
||||
import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.incompatible
|
||||
import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.*
|
||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||
import org.jetbrains.kotlin.types.TypeCheckerState
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
@@ -32,8 +33,8 @@ abstract class FakeOverrideBuilderStrategy(
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun linkFunctionFakeOverride(declaration: IrFunctionWithLateBinding, compatibilityMode: Boolean)
|
||||
protected abstract fun linkPropertyFakeOverride(declaration: IrPropertyWithLateBinding, compatibilityMode: Boolean)
|
||||
protected abstract fun linkFunctionFakeOverride(function: IrFunctionWithLateBinding, manglerCompatibleMode: Boolean)
|
||||
protected abstract fun linkPropertyFakeOverride(property: IrPropertyWithLateBinding, manglerCompatibleMode: Boolean)
|
||||
}
|
||||
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class) // Because of the LazyIR, have to use descriptors here.
|
||||
@@ -223,7 +224,7 @@ class IrOverridingUtil(
|
||||
|
||||
for (fromCurrent in membersFromCurrent) {
|
||||
val bound = extractAndBindOverridesForMember(fromCurrent, membersFromSupertypes)
|
||||
notOverridden.removeAll(bound)
|
||||
notOverridden -= bound
|
||||
}
|
||||
|
||||
val addedFakeOverrides = mutableListOf<IrOverridableMember>()
|
||||
@@ -237,30 +238,22 @@ class IrOverridingUtil(
|
||||
): Collection<IrOverridableMember> {
|
||||
val bound = ArrayList<IrOverridableMember>(descriptorsFromSuper.size)
|
||||
val overridden = mutableSetOf<IrOverridableMember>()
|
||||
|
||||
for (fromSupertype in descriptorsFromSuper) {
|
||||
val result = isOverridableBy(fromSupertype, fromCurrent/*, current*/).result
|
||||
val isVisibleForOverride =
|
||||
isVisibleForOverride(fromCurrent, fromSupertype.original)
|
||||
when (result) {
|
||||
// Note: We do allow overriding multiple FOs at once one of which is `isInline=true`.
|
||||
when (isOverridableBy(fromSupertype, fromCurrent, checkIsInlineFlag = true, checkReturnType = false).result) {
|
||||
OverrideCompatibilityInfo.Result.OVERRIDABLE -> {
|
||||
if (isVisibleForOverride) {
|
||||
overridden.add(fromSupertype)
|
||||
}
|
||||
bound.add(fromSupertype)
|
||||
if (isVisibleForOverride(fromCurrent, fromSupertype.original))
|
||||
overridden += fromSupertype
|
||||
bound += fromSupertype
|
||||
}
|
||||
OverrideCompatibilityInfo.Result.CONFLICT -> {
|
||||
// if (isVisibleForOverride) {
|
||||
// strategy.overrideConflict(fromSupertype, fromCurrent)
|
||||
// }
|
||||
|
||||
// Do nothing.
|
||||
bound.add(fromSupertype)
|
||||
}
|
||||
OverrideCompatibilityInfo.Result.INCOMPATIBLE -> {
|
||||
bound += fromSupertype
|
||||
}
|
||||
OverrideCompatibilityInfo.Result.INCOMPATIBLE -> Unit
|
||||
}
|
||||
}
|
||||
//strategy.setOverriddenDescriptors(fromCurrent, overridden)
|
||||
|
||||
fromCurrent.overriddenSymbols = overridden.map { it.original.symbol }
|
||||
|
||||
return bound
|
||||
@@ -404,7 +397,7 @@ class IrOverridingUtil(
|
||||
|
||||
private fun createAndBindFakeOverride(
|
||||
overridables: Collection<IrOverridableMember>,
|
||||
current: IrClass,
|
||||
currentClass: IrClass,
|
||||
addedFakeOverrides: MutableList<IrOverridableMember>,
|
||||
compatibilityMode: Boolean
|
||||
) {
|
||||
@@ -414,7 +407,7 @@ class IrOverridingUtil(
|
||||
// but we don't use invisible fakes in IR
|
||||
if (effectiveOverridden.isEmpty()) return
|
||||
|
||||
val modality = determineModalityForFakeOverride(effectiveOverridden, current)
|
||||
val modality = determineModalityForFakeOverride(effectiveOverridden, currentClass)
|
||||
val visibility = findMemberWithMaxVisibility(effectiveOverridden).visibility
|
||||
val mostSpecific = selectMostSpecificMember(effectiveOverridden)
|
||||
|
||||
@@ -600,120 +593,103 @@ class IrOverridingUtil(
|
||||
private fun getBothWaysOverridability(
|
||||
overriderDescriptor: IrOverridableMember,
|
||||
candidateDescriptor: IrOverridableMember
|
||||
): OverrideCompatibilityInfo.Result {
|
||||
): Result {
|
||||
val result1 = isOverridableBy(
|
||||
candidateDescriptor,
|
||||
overriderDescriptor
|
||||
//null
|
||||
overriderDescriptor,
|
||||
checkIsInlineFlag = false,
|
||||
checkReturnType = false
|
||||
).result
|
||||
|
||||
val result2 = isOverridableBy(
|
||||
overriderDescriptor,
|
||||
candidateDescriptor
|
||||
//null
|
||||
candidateDescriptor,
|
||||
checkIsInlineFlag = false,
|
||||
checkReturnType = false
|
||||
).result
|
||||
return if (result1 == OverrideCompatibilityInfo.Result.OVERRIDABLE && result2 == OverrideCompatibilityInfo.Result.OVERRIDABLE)
|
||||
OverrideCompatibilityInfo.Result.OVERRIDABLE
|
||||
else if (result1 == OverrideCompatibilityInfo.Result.CONFLICT || result2 == OverrideCompatibilityInfo.Result.CONFLICT)
|
||||
OverrideCompatibilityInfo.Result.CONFLICT
|
||||
else
|
||||
OverrideCompatibilityInfo.Result.INCOMPATIBLE
|
||||
|
||||
return if (result1 == result2) result1 else OverrideCompatibilityInfo.Result.INCOMPATIBLE
|
||||
}
|
||||
|
||||
private fun isOverridableBy(
|
||||
superMember: IrOverridableMember,
|
||||
subMember: IrOverridableMember,
|
||||
// subClass: IrClass?
|
||||
): OverrideCompatibilityInfo {
|
||||
return isOverridableBy(superMember, subMember/*, subClass*/, false)
|
||||
}
|
||||
|
||||
private fun isOverridableBy(
|
||||
superMember: IrOverridableMember,
|
||||
subMember: IrOverridableMember,
|
||||
// subClass: IrClass?, Would only be needed for external overridability conditions.
|
||||
checkIsInlineFlag: Boolean,
|
||||
checkReturnType: Boolean
|
||||
): OverrideCompatibilityInfo {
|
||||
val basicResult = isOverridableByWithoutExternalConditions(superMember, subMember, checkReturnType)
|
||||
return if (basicResult.result == OverrideCompatibilityInfo.Result.OVERRIDABLE)
|
||||
OverrideCompatibilityInfo.success()
|
||||
else
|
||||
basicResult
|
||||
return isOverridableByWithoutExternalConditions(superMember, subMember, checkIsInlineFlag, checkReturnType)
|
||||
// The frontend goes into external overridability condition details here, but don't deal with them in IR (yet?).
|
||||
}
|
||||
|
||||
private val IrOverridableMember.compiledValueParameters
|
||||
get() = when (this) {
|
||||
is IrSimpleFunction -> extensionReceiverParameter?.let { listOf(it) + valueParameters } ?: valueParameters
|
||||
is IrProperty -> getter!!.extensionReceiverParameter?.let { listOf(it) } ?: emptyList()
|
||||
else -> error("Unexpected declaration for compiledValueParameters: $this")
|
||||
}
|
||||
|
||||
private val IrOverridableMember.returnType
|
||||
get() = when (this) {
|
||||
is IrSimpleFunction -> this.returnType
|
||||
is IrProperty -> this.getter!!.returnType
|
||||
else -> error("Unexpected declaration for returnType: $this")
|
||||
}
|
||||
|
||||
private val IrOverridableMember.typeParameters
|
||||
get() = when (this) {
|
||||
is IrSimpleFunction -> this.typeParameters
|
||||
is IrProperty -> this.getter!!.typeParameters
|
||||
else -> error("Unexpected declaration for typeParameters: $this")
|
||||
}
|
||||
|
||||
private fun isOverridableByWithoutExternalConditions(
|
||||
superMember: IrOverridableMember,
|
||||
subMember: IrOverridableMember,
|
||||
checkIsInlineFlag: Boolean,
|
||||
checkReturnType: Boolean
|
||||
): OverrideCompatibilityInfo {
|
||||
val basicOverridability = getBasicOverridabilityProblem(superMember, subMember)
|
||||
if (basicOverridability != null) return basicOverridability
|
||||
val superTypeParameters: List<IrTypeParameter>
|
||||
val subTypeParameters: List<IrTypeParameter>
|
||||
|
||||
val superValueParameters = superMember.compiledValueParameters
|
||||
val subValueParameters = subMember.compiledValueParameters
|
||||
val superTypeParameters = superMember.typeParameters
|
||||
val subTypeParameters = subMember.typeParameters
|
||||
val superValueParameters: List<IrValueParameter>
|
||||
val subValueParameters: List<IrValueParameter>
|
||||
|
||||
if (superTypeParameters.size != subTypeParameters.size) {
|
||||
/* TODO: do we need this in IR?
|
||||
superValueParameters.forEachIndexed { index, superParameter ->
|
||||
if (!AbstractTypeChecker.equalTypes(
|
||||
defaultTypeCheckerContext as AbstractTypeCheckerContext,
|
||||
superParameter.type,
|
||||
subValueParameters[index].type
|
||||
)
|
||||
) {
|
||||
return OverrideCompatibilityInfo.incompatible("Type parameter number mismatch")
|
||||
when (superMember) {
|
||||
is IrSimpleFunction -> when {
|
||||
subMember !is IrSimpleFunction -> return incompatible("Member kind mismatch")
|
||||
superMember.hasExtensionReceiver != subMember.hasExtensionReceiver -> return incompatible("Receiver presence mismatch")
|
||||
superMember.isSuspend != subMember.isSuspend -> return incompatible("Incompatible suspendability")
|
||||
checkIsInlineFlag && superMember.isInline -> return incompatible("Inline function can't be overridden")
|
||||
|
||||
else -> {
|
||||
superTypeParameters = superMember.typeParameters
|
||||
subTypeParameters = subMember.typeParameters
|
||||
superValueParameters = superMember.compiledValueParameters
|
||||
subValueParameters = subMember.compiledValueParameters
|
||||
}
|
||||
}
|
||||
return OverrideCompatibilityInfo.conflict("Type parameter number mismatch")
|
||||
*/
|
||||
is IrProperty -> when {
|
||||
subMember !is IrProperty -> return incompatible("Member kind mismatch")
|
||||
superMember.getter.hasExtensionReceiver != subMember.getter.hasExtensionReceiver -> return incompatible("Receiver presence mismatch")
|
||||
checkIsInlineFlag && superMember.isInline -> return incompatible("Inline property can't be overridden")
|
||||
|
||||
return incompatible("Type parameter number mismatch")
|
||||
else -> {
|
||||
superTypeParameters = superMember.typeParameters
|
||||
subTypeParameters = subMember.typeParameters
|
||||
superValueParameters = superMember.compiledValueParameters
|
||||
subValueParameters = subMember.compiledValueParameters
|
||||
}
|
||||
}
|
||||
else -> error("Unexpected type of declaration: ${superMember::class.java}, $superMember")
|
||||
}
|
||||
|
||||
val typeCheckerState =
|
||||
createIrTypeCheckerState(
|
||||
IrTypeSystemContextWithAdditionalAxioms(
|
||||
typeSystem,
|
||||
superTypeParameters,
|
||||
subTypeParameters
|
||||
)
|
||||
when {
|
||||
superMember.name != subMember.name -> {
|
||||
// Check name after member kind checks. This way FO builder will first check types of overridable members and crash
|
||||
// if member types are not supported (ex: IrConstructor).
|
||||
return incompatible("Name mismatch")
|
||||
}
|
||||
|
||||
superTypeParameters.size != subTypeParameters.size -> return incompatible("Type parameter number mismatch")
|
||||
superValueParameters.size != subValueParameters.size -> return incompatible("Value parameter number mismatch")
|
||||
}
|
||||
|
||||
// TODO: check the bounds. See OverridingUtil.areTypeParametersEquivalent()
|
||||
// superTypeParameters.forEachIndexed { index, parameter ->
|
||||
// if (!AbstractTypeChecker.areTypeParametersEquivalent(
|
||||
// typeCheckerContext as AbstractTypeCheckerContext,
|
||||
// subTypeParameters[index].type,
|
||||
// parameter.type
|
||||
// )
|
||||
// ) return OverrideCompatibilityInfo.incompatible("Type parameter bounds mismatch")
|
||||
// }
|
||||
|
||||
val typeCheckerState = createIrTypeCheckerState(
|
||||
IrTypeSystemContextWithAdditionalAxioms(
|
||||
typeSystem,
|
||||
superTypeParameters,
|
||||
subTypeParameters
|
||||
)
|
||||
|
||||
/* TODO: check the bounds. See OverridingUtil.areTypeParametersEquivalent()
|
||||
superTypeParameters.forEachIndexed { index, parameter ->
|
||||
if (!AbstractTypeChecker.areTypeParametersEquivalent(
|
||||
typeCheckerContext as AbstractTypeCheckerContext,
|
||||
subTypeParameters[index].type,
|
||||
parameter.type
|
||||
)
|
||||
) return OverrideCompatibilityInfo.incompatible("Type parameter bounds mismatch")
|
||||
}
|
||||
*/
|
||||
|
||||
require(superValueParameters.size == subValueParameters.size)
|
||||
)
|
||||
|
||||
superValueParameters.forEachIndexed { index, parameter ->
|
||||
if (!AbstractTypeChecker.equalTypes(
|
||||
@@ -724,76 +700,59 @@ class IrOverridingUtil(
|
||||
) return incompatible("Value parameter type mismatch")
|
||||
}
|
||||
|
||||
if (superMember is IrSimpleFunction && subMember is IrSimpleFunction && superMember.isSuspend != subMember.isSuspend) {
|
||||
return OverrideCompatibilityInfo.conflict("Incompatible suspendability")
|
||||
}
|
||||
|
||||
if (checkReturnType) {
|
||||
if (!AbstractTypeChecker.isSubtypeOf(
|
||||
typeCheckerState,
|
||||
subMember.returnType,
|
||||
superMember.returnType
|
||||
)
|
||||
) return OverrideCompatibilityInfo.conflict("Return type mismatch")
|
||||
}
|
||||
return OverrideCompatibilityInfo.success()
|
||||
}
|
||||
|
||||
private fun getBasicOverridabilityProblem(
|
||||
superMember: IrOverridableMember,
|
||||
subMember: IrOverridableMember
|
||||
): OverrideCompatibilityInfo? {
|
||||
if (superMember is IrSimpleFunction && subMember !is IrSimpleFunction ||
|
||||
superMember is IrProperty && subMember !is IrProperty
|
||||
) {
|
||||
return incompatible("Member kind mismatch")
|
||||
}
|
||||
require((superMember is IrSimpleFunction || superMember is IrProperty)) {
|
||||
"This type of IrDeclaration cannot be checked for overridability: $superMember"
|
||||
) return conflict("Return type mismatch")
|
||||
}
|
||||
|
||||
return if (superMember.name != subMember.name) {
|
||||
incompatible("Name mismatch")
|
||||
} else
|
||||
checkReceiverAndParameterCount(superMember, subMember)
|
||||
}
|
||||
|
||||
private fun checkReceiverAndParameterCount(
|
||||
superMember: IrOverridableMember,
|
||||
subMember: IrOverridableMember
|
||||
): OverrideCompatibilityInfo? {
|
||||
return when (superMember) {
|
||||
is IrSimpleFunction -> {
|
||||
require(subMember is IrSimpleFunction)
|
||||
when {
|
||||
superMember.extensionReceiverParameter == null != (subMember.extensionReceiverParameter == null) -> {
|
||||
incompatible("Receiver presence mismatch")
|
||||
}
|
||||
superMember.valueParameters.size != subMember.valueParameters.size -> {
|
||||
incompatible("Value parameter number mismatch")
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
is IrProperty -> {
|
||||
require(subMember is IrProperty)
|
||||
if (superMember.getter?.extensionReceiverParameter == null != (subMember.getter?.extensionReceiverParameter == null)) {
|
||||
incompatible("Receiver presence mismatch")
|
||||
} else null
|
||||
}
|
||||
else -> error("Unxpected declaration for value parameter check: $this")
|
||||
}
|
||||
return success()
|
||||
}
|
||||
}
|
||||
|
||||
private val IrSimpleFunction?.hasExtensionReceiver: Boolean
|
||||
get() = this?.extensionReceiverParameter != null
|
||||
|
||||
private val IrSimpleFunction?.hasDispatchReceiver: Boolean
|
||||
get() = this?.dispatchReceiverParameter != null
|
||||
|
||||
private val IrSimpleFunction.compiledValueParameters: List<IrValueParameter>
|
||||
get() = ArrayList<IrValueParameter>(valueParameters.size + 1).apply {
|
||||
extensionReceiverParameter?.let(::add)
|
||||
addAll(valueParameters)
|
||||
}
|
||||
|
||||
private val IrProperty.compiledValueParameters: List<IrValueParameter>
|
||||
get() = getter?.extensionReceiverParameter?.let(::listOf).orEmpty()
|
||||
|
||||
private val IrProperty.typeParameters: List<IrTypeParameter>
|
||||
get() = getter?.typeParameters.orEmpty()
|
||||
|
||||
private val IrProperty.isInline: Boolean
|
||||
get() = getter?.isInline == true || setter?.isInline == true
|
||||
|
||||
private val IrOverridableMember.typeParameters: List<IrTypeParameter>
|
||||
get() = when (this) {
|
||||
is IrSimpleFunction -> typeParameters
|
||||
is IrProperty -> getter?.typeParameters.orEmpty()
|
||||
else -> error("Unexpected type of declaration: ${this::class.java}, $this")
|
||||
}
|
||||
|
||||
private val IrOverridableMember.returnType
|
||||
get() = when (this) {
|
||||
is IrSimpleFunction -> returnType
|
||||
is IrProperty -> getter!!.returnType
|
||||
else -> error("Unexpected type of declaration: ${this::class.java}, $this")
|
||||
}
|
||||
|
||||
fun IrSimpleFunction.isOverridableFunction(): Boolean =
|
||||
this.visibility != DescriptorVisibilities.PRIVATE &&
|
||||
this.dispatchReceiverParameter != null
|
||||
visibility != DescriptorVisibilities.PRIVATE && hasDispatchReceiver
|
||||
|
||||
fun IrProperty.isOverridableProperty(): Boolean =
|
||||
this.visibility != DescriptorVisibilities.PRIVATE &&
|
||||
(this.getter?.dispatchReceiverParameter != null ||
|
||||
this.setter?.dispatchReceiverParameter != null)
|
||||
visibility != DescriptorVisibilities.PRIVATE && (getter.hasDispatchReceiver || setter.hasDispatchReceiver)
|
||||
|
||||
fun IrDeclaration.isOverridableMemberOrAccessor(): Boolean = when (this) {
|
||||
is IrSimpleFunction -> isOverridableFunction()
|
||||
|
||||
@@ -5,9 +5,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.overrides
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithVisibility
|
||||
import org.jetbrains.kotlin.ir.declarations.IrOverridableDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrOverridableMember
|
||||
import org.jetbrains.kotlin.ir.util.parentClassOrNull
|
||||
|
||||
// The contents of this file is from VisibilityUtil.kt adapted to IR.
|
||||
// TODO: The code would better be commonized for descriptors, ir and fir.
|
||||
@@ -36,3 +38,25 @@ fun findMemberWithMaxVisibility(members: Collection<IrOverridableMember>): IrOve
|
||||
}
|
||||
return member ?: error("Could not find a visible member")
|
||||
}
|
||||
|
||||
fun IrDeclarationWithVisibility.isEffectivelyPrivate(): Boolean {
|
||||
fun DescriptorVisibility.isNonPrivate(): Boolean =
|
||||
this == DescriptorVisibilities.PUBLIC
|
||||
|| this == DescriptorVisibilities.PROTECTED
|
||||
|| this == DescriptorVisibilities.INTERNAL
|
||||
|
||||
return when {
|
||||
visibility.isNonPrivate() -> parentClassOrNull?.isEffectivelyPrivate() ?: false
|
||||
|
||||
visibility == DescriptorVisibilities.INVISIBLE_FAKE -> {
|
||||
val overridesOnlyPrivateDeclarations = (this as? IrOverridableDeclaration<*>)
|
||||
?.overriddenSymbols
|
||||
?.all { (it.owner as? IrDeclarationWithVisibility)?.isEffectivelyPrivate() == true }
|
||||
?: false
|
||||
|
||||
overridesOnlyPrivateDeclarations || (parentClassOrNull?.isEffectivelyPrivate() ?: false)
|
||||
}
|
||||
|
||||
else -> true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,15 +156,12 @@ abstract class ConstantValueGenerator(
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
fun generateAnnotationConstructorCall(annotationDescriptor: AnnotationDescriptor, realType: KotlinType? = null): IrConstructorCall? {
|
||||
val annotationType = realType ?: annotationDescriptor.type
|
||||
val annotationClassDescriptor = annotationType.constructor.declarationDescriptor
|
||||
if (annotationClassDescriptor !is ClassDescriptor) return null
|
||||
if (annotationClassDescriptor is NotFoundClasses.MockClassDescriptor) return null
|
||||
val annotationClassDescriptor = annotationType.constructor.declarationDescriptor as? ClassDescriptor ?: return null
|
||||
|
||||
assert(
|
||||
DescriptorUtils.isAnnotationClass(annotationClassDescriptor) ||
|
||||
(allowErrorTypeInAnnotations && annotationClassDescriptor is ErrorClassDescriptor)
|
||||
) {
|
||||
"Annotation class expected: $annotationClassDescriptor"
|
||||
when (annotationClassDescriptor) {
|
||||
is NotFoundClasses.MockClassDescriptor -> return null
|
||||
is ErrorClassDescriptor -> if (!allowErrorTypeInAnnotations) return null
|
||||
else -> if (!DescriptorUtils.isAnnotationClass(annotationClassDescriptor)) return null
|
||||
}
|
||||
|
||||
val primaryConstructorDescriptor = annotationClassDescriptor.unsubstitutedPrimaryConstructor
|
||||
|
||||
@@ -14,9 +14,9 @@ import org.jetbrains.kotlin.ir.builders.declarations.buildTypeParameter
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.linkage.partial.IrUnimplementedOverridesStrategy.ProcessAsFakeOverrides
|
||||
import org.jetbrains.kotlin.ir.overrides.FakeOverrideBuilderStrategy
|
||||
import org.jetbrains.kotlin.ir.overrides.IrOverridingUtil
|
||||
import org.jetbrains.kotlin.ir.overrides.IrUnimplementedOverridesStrategy.ProcessAsFakeOverrides
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrPropertySymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
@@ -1139,24 +1139,24 @@ private class FakeOverrideBuilderForLowerings : FakeOverrideBuilderStrategy(
|
||||
friendModules = emptyMap(),
|
||||
unimplementedOverridesStrategy = ProcessAsFakeOverrides
|
||||
) {
|
||||
override fun linkFunctionFakeOverride(declaration: IrFunctionWithLateBinding, compatibilityMode: Boolean) {
|
||||
declaration.acquireSymbol(IrSimpleFunctionSymbolImpl())
|
||||
override fun linkFunctionFakeOverride(function: IrFunctionWithLateBinding, manglerCompatibleMode: Boolean) {
|
||||
function.acquireSymbol(IrSimpleFunctionSymbolImpl())
|
||||
}
|
||||
|
||||
override fun linkPropertyFakeOverride(declaration: IrPropertyWithLateBinding, compatibilityMode: Boolean) {
|
||||
override fun linkPropertyFakeOverride(property: IrPropertyWithLateBinding, manglerCompatibleMode: Boolean) {
|
||||
val propertySymbol = IrPropertySymbolImpl()
|
||||
declaration.getter?.let { it.correspondingPropertySymbol = propertySymbol }
|
||||
declaration.setter?.let { it.correspondingPropertySymbol = propertySymbol }
|
||||
property.getter?.let { it.correspondingPropertySymbol = propertySymbol }
|
||||
property.setter?.let { it.correspondingPropertySymbol = propertySymbol }
|
||||
|
||||
declaration.acquireSymbol(propertySymbol)
|
||||
property.acquireSymbol(propertySymbol)
|
||||
|
||||
declaration.getter?.let {
|
||||
it.correspondingPropertySymbol = declaration.symbol
|
||||
linkFunctionFakeOverride(it as? IrFunctionWithLateBinding ?: error("Unexpected fake override getter: $it"), compatibilityMode)
|
||||
property.getter?.let {
|
||||
it.correspondingPropertySymbol = property.symbol
|
||||
linkFunctionFakeOverride(it as? IrFunctionWithLateBinding ?: error("Unexpected fake override getter: $it"), manglerCompatibleMode)
|
||||
}
|
||||
declaration.setter?.let {
|
||||
it.correspondingPropertySymbol = declaration.symbol
|
||||
linkFunctionFakeOverride(it as? IrFunctionWithLateBinding ?: error("Unexpected fake override setter: $it"), compatibilityMode)
|
||||
property.setter?.let {
|
||||
it.correspondingPropertySymbol = property.symbol
|
||||
linkFunctionFakeOverride(it as? IrFunctionWithLateBinding ?: error("Unexpected fake override setter: $it"), manglerCompatibleMode)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1329,8 +1329,8 @@ private fun IrSimpleFunction.copyAndRenameConflictingTypeParametersFrom(
|
||||
val IrSymbol.isSuspend: Boolean
|
||||
get() = this is IrSimpleFunctionSymbol && owner.isSuspend
|
||||
|
||||
fun IrSimpleFunction.allOverridden(includeSelf: Boolean = false): List<IrSimpleFunction> {
|
||||
val result = mutableListOf<IrSimpleFunction>()
|
||||
fun <T : IrOverridableDeclaration<*>> T.allOverridden(includeSelf: Boolean = false): List<T> {
|
||||
val result = mutableListOf<T>()
|
||||
if (includeSelf) {
|
||||
result.add(this)
|
||||
}
|
||||
@@ -1341,7 +1341,8 @@ fun IrSimpleFunction.allOverridden(includeSelf: Boolean = false): List<IrSimpleF
|
||||
when (overridden.size) {
|
||||
0 -> return result
|
||||
1 -> {
|
||||
current = overridden[0].owner
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
current = overridden[0].owner as T
|
||||
result.add(current)
|
||||
}
|
||||
else -> {
|
||||
@@ -1353,9 +1354,9 @@ fun IrSimpleFunction.allOverridden(includeSelf: Boolean = false): List<IrSimpleF
|
||||
}
|
||||
}
|
||||
|
||||
private fun computeAllOverridden(function: IrSimpleFunction, result: MutableSet<IrSimpleFunction>) {
|
||||
for (overriddenSymbol in function.overriddenSymbols) {
|
||||
val override = overriddenSymbol.owner
|
||||
private fun <T : IrOverridableDeclaration<*>> computeAllOverridden(overridable: T, result: MutableSet<T>) {
|
||||
for (overriddenSymbol in overridable.overriddenSymbols) {
|
||||
@Suppress("UNCHECKED_CAST") val override = overriddenSymbol.owner as T
|
||||
if (result.add(override)) {
|
||||
computeAllOverridden(override, result)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user