From af18b10da9d1e20b1b35831a3fb5e508048a2576 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Thu, 14 Oct 2021 08:17:07 +0300 Subject: [PATCH] JVM_IR KT-49203 generate stubs for not found classes --- .../kotlin/backend/jvm/JvmIrCodegenFactory.kt | 6 ++-- .../DeclarationStubGeneratorImpl.kt | 24 +++++++++++--- .../psi2ir/generators/FunctionGenerator.kt | 32 ++----------------- .../ir/util/ExternalDependenciesGenerator.kt | 17 ++++------ .../kotlin/ir/util/TypeTranslator.kt | 3 -- .../common/serialization/KotlinIrLinker.kt | 5 +-- .../codegen/box/fir/notFoundClasses.kt | 1 - 7 files changed, 37 insertions(+), 51 deletions(-) diff --git a/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmIrCodegenFactory.kt b/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmIrCodegenFactory.kt index 93e9ac26d38..e60e868c62c 100644 --- a/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmIrCodegenFactory.kt +++ b/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmIrCodegenFactory.kt @@ -34,6 +34,7 @@ import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator +import org.jetbrains.kotlin.psi2ir.generators.DeclarationStubGeneratorForNotFoundClasses import org.jetbrains.kotlin.psi2ir.generators.DeclarationStubGeneratorImpl import org.jetbrains.kotlin.psi2ir.generators.fragments.EvaluatorFragmentInfo import org.jetbrains.kotlin.psi2ir.generators.fragments.FragmentContext @@ -145,10 +146,11 @@ open class JvmIrCodegenFactory( irLinker.deserializeIrModuleHeader(it, kotlinLibrary, _moduleName = it.name.asString()) } + val stubGeneratorForMissingClasses = DeclarationStubGeneratorForNotFoundClasses(stubGenerator) val irProviders = if (evaluatorFragmentInfoForPsi2Ir != null) { - listOf(stubGenerator, irLinker) + listOf(stubGenerator, irLinker, stubGeneratorForMissingClasses) } else { - listOf(irLinker) + listOf(irLinker, stubGeneratorForMissingClasses) } val irModuleFragment = diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DeclarationStubGeneratorImpl.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DeclarationStubGeneratorImpl.kt index 8ca4ed81d11..089c41948fb 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DeclarationStubGeneratorImpl.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DeclarationStubGeneratorImpl.kt @@ -6,14 +6,15 @@ package org.jetbrains.kotlin.psi2ir.generators import org.jetbrains.kotlin.descriptors.ModuleDescriptor +import org.jetbrains.kotlin.descriptors.NotFoundClasses import org.jetbrains.kotlin.ir.IrBuiltIns +import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI +import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.lazy.LazyScopedTypeParametersResolver import org.jetbrains.kotlin.ir.linkage.IrDeserializer import org.jetbrains.kotlin.ir.linkage.IrProvider -import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator -import org.jetbrains.kotlin.ir.util.StubGeneratorExtensions -import org.jetbrains.kotlin.ir.util.SymbolTable -import org.jetbrains.kotlin.ir.util.TypeTranslator +import org.jetbrains.kotlin.ir.symbols.IrSymbol +import org.jetbrains.kotlin.ir.util.* class DeclarationStubGeneratorImpl( moduleDescriptor: ModuleDescriptor, @@ -45,3 +46,18 @@ fun generateTypicalIrProviderList( ) return listOfNotNull(deserializer, stubGenerator) } + + +@OptIn(ObsoleteDescriptorBasedAPI::class) +class DeclarationStubGeneratorForNotFoundClasses( + private val stubGenerator: DeclarationStubGeneratorImpl +) : IrProvider { + + override fun getDeclaration(symbol: IrSymbol): IrDeclaration? { + if (symbol.isBound) return null + + val classDescriptor = symbol.descriptor as? NotFoundClasses.MockClassDescriptor + ?: return null + return stubGenerator.generateClassStub(classDescriptor) + } +} diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/FunctionGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/FunctionGenerator.kt index 811bd84036a..0e4c6e83514 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/FunctionGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/FunctionGenerator.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.psi2ir.generators import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.IrElement +import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.IrBlockBody @@ -18,10 +19,6 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl -import org.jetbrains.kotlin.ir.types.IrErrorType -import org.jetbrains.kotlin.ir.types.IrSimpleType -import org.jetbrains.kotlin.ir.types.IrType -import org.jetbrains.kotlin.ir.types.IrTypeProjection import org.jetbrains.kotlin.ir.types.impl.IrUninitializedType import org.jetbrains.kotlin.ir.util.declareSimpleFunctionWithOverrides import org.jetbrains.kotlin.name.Name @@ -39,6 +36,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal import org.jetbrains.kotlin.resolve.descriptorUtil.propertyIfAccessor import org.jetbrains.kotlin.utils.addToStdlib.safeAs +@ObsoleteDescriptorBasedAPI class FunctionGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGeneratorExtension(declarationGenerator) { constructor(context: GeneratorContext) : this(DeclarationGenerator(context)) @@ -74,31 +72,8 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio .buildWithScope { irFunction -> generateFunctionParameterDeclarationsAndReturnType(irFunction, ktElement, null) } - .takeUnless { irFunction -> - irFunction.containsErrorTypesInSignature() - } } - private fun IrSimpleFunction.containsErrorTypesInSignature(): Boolean { - if (this.typeParameters.any { it.superTypes.any { it.containsErrorType() } }) return true - this.dispatchReceiverParameter?.let { - if (it.type.containsErrorType()) return true - } - this.extensionReceiverParameter?.let { - if (it.type.containsErrorType()) return true - } - if (this.valueParameters.any { it.type.containsErrorType() }) return true - if (this.returnType.containsErrorType()) return true - return false - } - - private fun IrType.containsErrorType(): Boolean = - when (this) { - is IrErrorType -> true - is IrSimpleType -> arguments.any { it is IrTypeProjection && it.type.containsErrorType() } - else -> false - } - private inline fun declareSimpleFunction( ktFunction: KtFunction, ktReceiver: KtElement?, @@ -234,8 +209,7 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio property: PropertyDescriptor, irAccessor: IrSimpleFunction ): IrExpression? { - val containingDeclaration = property.containingDeclaration - return when (containingDeclaration) { + return when (val containingDeclaration = property.containingDeclaration) { is ClassDescriptor -> { val thisAsReceiverParameter = containingDeclaration.thisAsReceiverParameter IrGetValueImpl( diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/ExternalDependenciesGenerator.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/ExternalDependenciesGenerator.kt index 82303420405..c3a3b82c13a 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/ExternalDependenciesGenerator.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/ExternalDependenciesGenerator.kt @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.jetbrains.kotlin.ir.util import org.jetbrains.kotlin.analyzer.CompilationErrorException @@ -26,21 +25,19 @@ class ExternalDependenciesGenerator( val symbolTable: SymbolTable, private val irProviders: List ) { + fun generateUnboundSymbolsAsDependencies() { // There should be at most one DeclarationStubGenerator (none in closed world?) irProviders.singleOrNull { it is DeclarationStubGenerator }?.let { (it as DeclarationStubGenerator).unboundSymbolGeneration = true } - /* - Deserializing a reference may lead to new unbound references, so we loop until none are left. - */ - var unbound = setOf() - lateinit var prevUnbound: Set - try { - do { - prevUnbound = unbound - unbound = symbolTable.allUnbound + // Deserializing a reference may lead to new unbound references, so we loop until none are left. + try { + var unbound = setOf() + do { + val prevUnbound = unbound + unbound = symbolTable.allUnbound for (symbol in unbound) { // Symbol could get bound as a side effect of deserializing other symbols. if (!symbol.isBound) { diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/TypeTranslator.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/TypeTranslator.kt index ad605f10f20..cda36468352 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/TypeTranslator.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/TypeTranslator.kt @@ -145,9 +145,6 @@ abstract class TypeTranslator( lowerType.constructor.declarationDescriptor as? ClassDescriptor ?: throw AssertionError("No class descriptor for lower type $lowerType of $approximatedType") annotations = translateTypeAnnotations(upperType, approximatedType) - if (lowerTypeDescriptor is NotFoundClasses.MockClassDescriptor) { - return IrErrorTypeImpl(approximatedType, annotations, variance) - } classifier = symbolTable.referenceClass(lowerTypeDescriptor) arguments = when { approximatedType is RawType -> diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt index 49dc3f78313..c1c71d29121 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt @@ -130,7 +130,6 @@ abstract class KotlinIrLinker( } override fun getDeclaration(symbol: IrSymbol): IrDeclaration? { - if (!symbol.isPublicApi) { if (symbol.hasDescriptor) { val descriptor = symbol.descriptor @@ -142,7 +141,9 @@ abstract class KotlinIrLinker( if (!symbol.isBound) { try { - findDeserializedDeclarationForSymbol(symbol) ?: tryResolveCustomDeclaration(symbol) ?: return null + findDeserializedDeclarationForSymbol(symbol) + ?: tryResolveCustomDeclaration(symbol) + ?: return null } catch (e: IrSymbolTypeMismatchException) { throw SymbolTypeMismatch(e, deserializersForModules.values, userVisibleIrModulesSupport).raiseIssue(messageLogger) } diff --git a/compiler/testData/codegen/box/fir/notFoundClasses.kt b/compiler/testData/codegen/box/fir/notFoundClasses.kt index c8ac3965353..7464bc7cde3 100644 --- a/compiler/testData/codegen/box/fir/notFoundClasses.kt +++ b/compiler/testData/codegen/box/fir/notFoundClasses.kt @@ -1,5 +1,4 @@ // WITH_RUNTIME -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // MODULE: lib1