From 31d73c5d79548135daa786d988098ac313220ac6 Mon Sep 17 00:00:00 2001 From: Roman Artemev Date: Mon, 27 Jan 2020 16:10:26 +0300 Subject: [PATCH] [Psi2Ir] Move to new linkage scheme based on IdSignature Now SymbolTable operates with two types of symbols (public and private) In case of Public symbol IdSignature is used as table key Private one uses descriptor as the key in similar scheme as before --- .../compiler/KotlinToJVMBytecodeCompiler.kt | 7 +- .../kotlin/fir/backend/Fir2IrConverter.kt | 7 +- .../kotlin/fir/AbstractFir2IrTextTest.kt | 6 +- .../kotlin/backend/jvm/JvmBackendFacade.kt | 8 +- .../kotlin/psi2ir/Psi2IrTranslator.kt | 9 +- .../generators/DataClassMembersGenerator.kt | 18 +- .../psi2ir/generators/GeneratorContext.kt | 9 +- .../kotlin/ir/descriptors/IrBuiltIns.kt | 15 +- .../jetbrains/kotlin/ir/util/SymbolTable.kt | 493 ++++++++++++------ .../jetbrains/kotlin/ir/backend/js/klib.kt | 22 +- .../kotlin/codegen/GenerationUtils.kt | 4 +- .../kotlin/ir/AbstractIrGeneratorTestCase.kt | 11 +- .../kotlin/ir/AbstractIrTextTestCase.kt | 6 +- .../plugin/impl/ScriptJsCompilerImpls.kt | 4 +- .../repl/js/JsCoreScriptingCompiler.kt | 8 +- .../scripting/repl/js/JsReplCompiler.kt | 4 +- .../repl/js/JsScriptDependencyCompiler.kt | 8 +- 17 files changed, 433 insertions(+), 206 deletions(-) diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt index 777879bf03e..1b126f8e961 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt @@ -31,8 +31,10 @@ import org.jetbrains.kotlin.asJava.finder.JavaElementFinder import org.jetbrains.kotlin.backend.common.output.OutputFileCollection import org.jetbrains.kotlin.backend.common.output.SimpleOutputFileCollection import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig +import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory import org.jetbrains.kotlin.backend.jvm.jvmPhases +import org.jetbrains.kotlin.backend.jvm.serialization.JvmManglerDesc import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.cli.common.ExitCode import org.jetbrains.kotlin.cli.common.checkKotlinPackageUsage @@ -339,8 +341,11 @@ object KotlinToJVMBytecodeCompiler { throw e } } + + val signaturer = IdSignatureDescriptor(JvmManglerDesc()) + val (moduleFragment, symbolTable, sourceManager) = - Fir2IrConverter.createModuleFragment(session, firFiles, moduleConfiguration.languageVersionSettings) + Fir2IrConverter.createModuleFragment(session, firFiles, moduleConfiguration.languageVersionSettings, signaturer = signaturer) val dummyBindingContext = NoScopeRecordCliBindingTrace().bindingContext val codegenFactory = JvmIrCodegenFactory(moduleConfiguration.get(CLIConfigurationKeys.PHASE_CONFIG) ?: PhaseConfig(jvmPhases)) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt index 7c8e83979c4..a26d916920f 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt @@ -24,15 +24,16 @@ object Fir2IrConverter { session: FirSession, firFiles: List, languageVersionSettings: LanguageVersionSettings, - fakeOverrideMode: FakeOverrideMode = FakeOverrideMode.NORMAL + fakeOverrideMode: FakeOverrideMode = FakeOverrideMode.NORMAL, + signaturer: IdSignatureComposer ): Fir2IrResult { val moduleDescriptor = FirModuleDescriptor(session) - val symbolTable = SymbolTable() + val symbolTable = SymbolTable(signaturer) val constantValueGenerator = ConstantValueGenerator(moduleDescriptor, symbolTable) val typeTranslator = TypeTranslator(symbolTable, languageVersionSettings, moduleDescriptor.builtIns) constantValueGenerator.typeTranslator = typeTranslator typeTranslator.constantValueGenerator = constantValueGenerator - val builtIns = IrBuiltIns(moduleDescriptor.builtIns, typeTranslator, symbolTable) + val builtIns = IrBuiltIns(moduleDescriptor.builtIns, typeTranslator, signaturer, symbolTable) val sourceManager = PsiSourceManager() val fir2irTransformer = Fir2IrVisitor(session, moduleDescriptor, symbolTable, sourceManager, builtIns, fakeOverrideMode) val irFiles = mutableListOf() diff --git a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/AbstractFir2IrTextTest.kt b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/AbstractFir2IrTextTest.kt index b9d0827c38d..ac7924fa123 100644 --- a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/AbstractFir2IrTextTest.kt +++ b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/AbstractFir2IrTextTest.kt @@ -11,6 +11,8 @@ import com.intellij.psi.PsiElementFinder import com.intellij.psi.search.GlobalSearchScope import junit.framework.TestCase import org.jetbrains.kotlin.asJava.finder.JavaElementFinder +import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor +import org.jetbrains.kotlin.backend.jvm.serialization.JvmManglerDesc import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.fir.backend.Fir2IrConverter @@ -92,8 +94,10 @@ abstract class AbstractFir2IrTextTest : AbstractIrTextTestCase() { } } + val signaturer = IdSignatureDescriptor(JvmManglerDesc()) + return Fir2IrConverter.createModuleFragment( - session, firFiles, myEnvironment.configuration.languageVersionSettings + session, firFiles, myEnvironment.configuration.languageVersionSettings, signaturer = signaturer ).irModuleFragment } } \ No newline at end of file diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendFacade.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendFacade.kt index b5903a57dee..27a3650cc51 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendFacade.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendFacade.kt @@ -11,11 +11,13 @@ import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig import org.jetbrains.kotlin.backend.jvm.codegen.ClassCodegen import org.jetbrains.kotlin.backend.jvm.lower.MultifileFacadeFileEntry +import org.jetbrains.kotlin.backend.jvm.serialization.JvmIdSignatureDescriptor +import org.jetbrains.kotlin.backend.jvm.serialization.JvmManglerDesc import org.jetbrains.kotlin.codegen.state.GenerationState +import org.jetbrains.kotlin.idea.MainFunctionDetector import org.jetbrains.kotlin.descriptors.konan.KlibModuleOrigin import org.jetbrains.kotlin.ir.backend.jvm.serialization.EmptyLoggingContext import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmIrLinker -import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmMangler import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.types.defaultType @@ -27,7 +29,9 @@ import org.jetbrains.kotlin.psi2ir.PsiSourceManager object JvmBackendFacade { fun doGenerateFiles(files: Collection, state: GenerationState, phaseConfig: PhaseConfig) { val extensions = JvmGeneratorExtensions() - val psi2ir = Psi2IrTranslator(state.languageVersionSettings, mangler = JvmMangler) + val mangler = JvmManglerDesc(MainFunctionDetector(state.bindingContext, state.languageVersionSettings)) + val signaturer = JvmIdSignatureDescriptor(mangler) + val psi2ir = Psi2IrTranslator(state.languageVersionSettings, signaturer = signaturer) val psi2irContext = psi2ir.createGeneratorContext(state.module, state.bindingContext, extensions = extensions) for (extension in IrGenerationExtension.getInstances(state.project)) { diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt index edc5b0ac6e3..1438dc9681c 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt @@ -35,7 +35,7 @@ typealias Psi2IrPostprocessingStep = (IrModuleFragment) -> Unit class Psi2IrTranslator( val languageVersionSettings: LanguageVersionSettings, val configuration: Psi2IrConfiguration = Psi2IrConfiguration(), - val mangler: KotlinMangler? = null + val signaturer: IdSignatureComposer ) { private val postprocessingSteps = SmartList() @@ -59,10 +59,10 @@ class Psi2IrTranslator( fun createGeneratorContext( moduleDescriptor: ModuleDescriptor, bindingContext: BindingContext, - symbolTable: SymbolTable = SymbolTable(mangler), + symbolTable: SymbolTable = SymbolTable(signaturer), extensions: GeneratorExtensions = GeneratorExtensions() ): GeneratorContext = - GeneratorContext(configuration, moduleDescriptor, bindingContext, languageVersionSettings, symbolTable, extensions) + GeneratorContext(configuration, moduleDescriptor, bindingContext, languageVersionSettings, symbolTable, extensions, signaturer) fun generateModuleFragment( context: GeneratorContext, @@ -73,13 +73,12 @@ class Psi2IrTranslator( val moduleGenerator = ModuleGenerator(context) val irModule = moduleGenerator.generateModuleFragmentWithoutDependencies(ktFiles) - expectDescriptorToSymbol ?. let { referenceExpectsForUsedActuals(it, context.symbolTable, irModule) } + expectDescriptorToSymbol?.let { referenceExpectsForUsedActuals(it, context.symbolTable, irModule) } irModule.patchDeclarationParents() postprocess(context, irModule) // do not generate unbound symbols before postprocessing, // since plugins must work with non-lazy IR moduleGenerator.generateUnboundSymbolsAsDependencies(irProviders) - irModule.computeUniqIdForDeclarations(context.symbolTable) return irModule } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DataClassMembersGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DataClassMembersGenerator.kt index b99539a1993..9f2aa630462 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DataClassMembersGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DataClassMembersGenerator.kt @@ -27,6 +27,8 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl import org.jetbrains.kotlin.ir.expressions.mapTypeParameters import org.jetbrains.kotlin.ir.expressions.mapValueParameters +import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol +import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.util.declareSimpleFunctionWithOverrides import org.jetbrains.kotlin.ir.util.properties import org.jetbrains.kotlin.ir.util.referenceFunction @@ -200,16 +202,16 @@ class DataClassMembersGenerator( .let { context.symbolTable.referenceFunction(it) } - private fun getHashCodeFunction(type: KotlinType): FunctionDescriptor = + private fun getHashCodeFunction(type: KotlinType, symbolResolve: (FunctionDescriptor) -> IrSimpleFunctionSymbol): IrSimpleFunctionSymbol = when (val typeConstructorDescriptor = type.constructor.declarationDescriptor) { is ClassDescriptor -> if (KotlinBuiltIns.isArrayOrPrimitiveArray(typeConstructorDescriptor)) - context.irBuiltIns.dataClassArrayMemberHashCode + context.irBuiltIns.dataClassArrayMemberHashCodeSymbol else - type.memberScope.findFirstFunction("hashCode") { it.valueParameters.isEmpty() } + symbolResolve(type.memberScope.findFirstFunction("hashCode") { it.valueParameters.isEmpty() }) is TypeParameterDescriptor -> - getHashCodeFunction(typeConstructorDescriptor.representativeUpperBound) + getHashCodeFunction(typeConstructorDescriptor.representativeUpperBound, symbolResolve) else -> throw AssertionError("Unexpected type: $type") @@ -255,10 +257,12 @@ class DataClassMembersGenerator( } private fun MemberFunctionBuilder.getHashCodeOf(kotlinType: KotlinType, irValue: IrExpression): IrExpression { - val hashCodeFunctionDescriptor = getHashCodeFunction(kotlinType) - val hashCodeFunctionSymbol = declarationGenerator.context.symbolTable.referenceFunction(hashCodeFunctionDescriptor.original) + val hashCodeFunctionSymbol = getHashCodeFunction(kotlinType) { + declarationGenerator.context.symbolTable.referenceSimpleFunction(it.original) + } + return irCall(hashCodeFunctionSymbol, context.irBuiltIns.intType).apply { - if (hashCodeFunctionDescriptor.dispatchReceiverParameter != null) { + if (hashCodeFunctionSymbol.descriptor.dispatchReceiverParameter != null) { dispatchReceiver = irValue } else { putValueArgument(0, irValue) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/GeneratorContext.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/GeneratorContext.kt index cfe3493c6da..a07273c669f 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/GeneratorContext.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/GeneratorContext.kt @@ -24,9 +24,7 @@ import org.jetbrains.kotlin.descriptors.NotFoundClasses import org.jetbrains.kotlin.ir.builders.IrGeneratorContext import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression -import org.jetbrains.kotlin.ir.util.ConstantValueGenerator -import org.jetbrains.kotlin.ir.util.SymbolTable -import org.jetbrains.kotlin.ir.util.TypeTranslator +import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration import org.jetbrains.kotlin.psi2ir.PsiSourceManager import org.jetbrains.kotlin.resolve.BindingContext @@ -38,7 +36,8 @@ class GeneratorContext( val bindingContext: BindingContext, val languageVersionSettings: LanguageVersionSettings, val symbolTable: SymbolTable, - val extensions: GeneratorExtensions + val extensions: GeneratorExtensions, + signaturer: IdSignatureComposer ) : IrGeneratorContext() { val constantValueGenerator: ConstantValueGenerator = ConstantValueGenerator(moduleDescriptor, symbolTable) @@ -50,7 +49,7 @@ class GeneratorContext( constantValueGenerator.typeTranslator = typeTranslator } - override val irBuiltIns: IrBuiltIns = IrBuiltIns(moduleDescriptor.builtIns, typeTranslator, symbolTable) + override val irBuiltIns: IrBuiltIns = IrBuiltIns(moduleDescriptor.builtIns, typeTranslator, signaturer, symbolTable) val sourceManager = PsiSourceManager() diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltIns.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltIns.kt index 6b7b072aeff..1cbf9a75a20 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltIns.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltIns.kt @@ -13,7 +13,6 @@ import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl import org.jetbrains.kotlin.incremental.components.NoLookupLocation -import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginImpl import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl import org.jetbrains.kotlin.ir.symbols.IrClassSymbol @@ -27,8 +26,7 @@ import org.jetbrains.kotlin.ir.types.impl.buildSimpleType import org.jetbrains.kotlin.ir.types.impl.originalKotlinType import org.jetbrains.kotlin.ir.types.makeNullable import org.jetbrains.kotlin.ir.types.withHasQuestionMark -import org.jetbrains.kotlin.ir.util.SymbolTable -import org.jetbrains.kotlin.ir.util.TypeTranslator +import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.storage.LockBasedStorageManager @@ -37,6 +35,7 @@ import org.jetbrains.kotlin.types.* class IrBuiltIns( val builtIns: KotlinBuiltIns, private val typeTranslator: TypeTranslator, + signaturer: IdSignatureComposer, outerSymbolTable: SymbolTable? = null ) { val languageVersionSettings = typeTranslator.languageVersionSettings @@ -45,7 +44,7 @@ class IrBuiltIns( val irBuiltInsSymbols = mutableListOf() - private val symbolTable = outerSymbolTable ?: SymbolTable() + private val symbolTable = outerSymbolTable ?: SymbolTable(signaturer) private val packageFragmentDescriptor = IrBuiltinsPackageFragmentDescriptorImpl(builtInsModule, KOTLIN_INTERNAL_IR_FQN) private val packageFragment = @@ -56,8 +55,9 @@ class IrBuiltIns( fun defineOperator(name: String, returnType: IrType, valueParameterTypes: List): IrSimpleFunctionSymbol { val descriptor = WrappedSimpleFunctionDescriptor() - val symbol = symbolTable.declareSimpleFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, BUILTIN_OPERATOR, descriptor) { - val suffix = valueParameterTypes.joinToString(":", "[", "]") { t -> t.originalKotlinType?.toString() ?: "T" } + val suffix = valueParameterTypes.joinToString(":", "[", "]") { t -> t.originalKotlinType?.toString() ?: "T" } + val mangle = "operator#$name@$suffix" + val symbol = symbolTable.declareBuiltInOperator(descriptor, mangle) { val operator = IrBuiltInOperator(it, Name.identifier(name), returnType, suffix) operator.parent = packageFragment packageFragment.declarations += operator @@ -135,7 +135,8 @@ class IrBuiltIns( buildSimpleType() } - return symbolTable.declareSimpleFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, BUILTIN_OPERATOR, descriptor) { + val mangle = "operator#$name@:!!" + return symbolTable.declareBuiltInOperator(descriptor, mangle) { val operator = IrBuiltInOperator(it, name, returnIrType, ":!!") operator.parent = packageFragment packageFragment.declarations += operator diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/SymbolTable.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/SymbolTable.kt index 460ce7d883c..a22d8a3ecf2 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/SymbolTable.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/SymbolTable.kt @@ -19,20 +19,17 @@ package org.jetbrains.kotlin.ir.util import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.* import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyDeclarationBase import org.jetbrains.kotlin.ir.declarations.lazy.IrLazySymbolTable +import org.jetbrains.kotlin.ir.descriptors.* import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpressionBody import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.impl.* import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.impl.IrUninitializedType -import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid -import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid -import org.jetbrains.kotlin.ir.visitors.acceptVoid interface IrProvider { fun getDeclaration(symbol: IrSymbol): IrDeclaration? @@ -42,7 +39,7 @@ interface IrProvider { * Extension of [IrProvider] which always produces inheritors of [IrLazyDeclarationBase]. * Thus, it needs [declarationStubGenerator] to be able to produce IR declarations. */ -interface LazyIrProvider: IrProvider { +interface LazyIrProvider : IrProvider { var declarationStubGenerator: DeclarationStubGenerator override fun getDeclaration(symbol: IrSymbol): IrLazyDeclarationBase? @@ -70,51 +67,31 @@ interface ReferenceSymbolTable { fun referenceTypeAlias(descriptor: TypeAliasDescriptor): IrTypeAliasSymbol + fun referenceClassFromLinker(descriptor: ClassDescriptor, sig: IdSignature): IrClassSymbol + fun referenceConstructorFromLinker(descriptor: ClassConstructorDescriptor, sig: IdSignature): IrConstructorSymbol + fun referenceEnumEntryFromLinker(descriptor: ClassDescriptor, sig: IdSignature): IrEnumEntrySymbol + fun referenceFieldFromLinker(descriptor: PropertyDescriptor, sig: IdSignature): IrFieldSymbol + fun referencePropertyFromLinker(descriptor: PropertyDescriptor, sig: IdSignature): IrPropertySymbol + fun referenceSimpleFunctionFromLinker(descriptor: FunctionDescriptor, sig: IdSignature): IrSimpleFunctionSymbol + fun referenceTypeParameterFromLinker(classifier: TypeParameterDescriptor, sig: IdSignature): IrTypeParameterSymbol + fun referenceTypeAliasFromLinker(descriptor: TypeAliasDescriptor, sig: IdSignature): IrTypeAliasSymbol + fun enterScope(owner: DeclarationDescriptor) fun leaveScope(owner: DeclarationDescriptor) - - // Referencing by UniqId produces symbols with WrappedDescriptor - fun referenceClass(uniqId: UniqId): IrClassSymbol - fun referenceConstructor(uniqId: UniqId): IrConstructorSymbol - fun referenceEnumEntry(uniqId: UniqId): IrEnumEntrySymbol - fun referenceField(uniqId: UniqId): IrFieldSymbol - fun referenceProperty(uniqId: UniqId): IrPropertySymbol - fun referenceSimpleFunction(uniqId: UniqId): IrSimpleFunctionSymbol - fun referenceTypeParameter(uniqId: UniqId): IrTypeParameterSymbol - fun referenceTypeAlias(uniqId: UniqId): IrTypeAliasSymbol - - // Should only be called when the declaration is in a `ready` state -- with a full chain of parents, - // type and value parameters etc. - fun computeUniqId(declaration: IrDeclaration) } -open class SymbolTable(val mangler: KotlinMangler? = null) : ReferenceSymbolTable { +open class SymbolTable(private val signaturer: IdSignatureComposer) : ReferenceSymbolTable { @Suppress("LeakingThis") val lazyWrapper = IrLazySymbolTable(this) - private fun IrSymbolOwner.getUniqId() = mangler?.run { - (this@getUniqId as? IrDeclaration)?.hashedMangle?.let { UniqId(it) } ?: UniqId.NONE - } ?: UniqId.NONE - - fun IrSymbol.setUniqId() { - if (isBound) { - val oldUid = uniqId - val newUid = owner.getUniqId() - assert(oldUid == UniqId.NONE || oldUid == newUid) - uniqId = newUid - } - } - private abstract inner class SymbolTableBase> { val unboundSymbols = linkedSetOf() - val unboundUniqIds = linkedSetOf() abstract fun get(d: D): S? abstract fun set(d: D, s: S) - abstract fun get(uid: UniqId): S? - abstract fun set(uid: UniqId, s: S) + abstract fun get(sig: IdSignature): S? inline fun declare(d: D, createSymbol: () -> S, createOwner: (S) -> B): B { @Suppress("UNCHECKED_CAST") @@ -134,12 +111,22 @@ open class SymbolTable(val mangler: KotlinMangler? = null) : ReferenceSymbolTabl return createOwner(symbol) } - fun computeUniqId(b: B) { - if (b !is IrDeclaration) return - val symbol = b.symbol as S - symbol.setUniqId() - set(symbol.uniqId, symbol) - unboundSymbols.remove(symbol) + inline fun declare(sig: IdSignature, d: D, createSymbol: () -> S, createOwner: (S) -> B): B { + @Suppress("UNCHECKED_CAST") + val d0 = d.original as D + assert(d0 === d) { + "Non-original descriptor in declaration: $d\n\tExpected: $d0" + } + val existing = get(sig) + val symbol = if (existing == null) { + val new = createSymbol() + set(d0, new) + new + } else { + unboundSymbols.remove(existing) + existing + } + return createOwner(symbol) } inline fun referenced(d: D, orElse: () -> S): S { @@ -160,62 +147,96 @@ open class SymbolTable(val mangler: KotlinMangler? = null) : ReferenceSymbolTabl return s } - inline fun referenced(uid: UniqId, orElse: () -> S): S { - return get(uid) ?: run { + inline fun referenced(sig: IdSignature, orElse: () -> S): S { + return get(sig) ?: run { val new = orElse() assert(unboundSymbols.add(new)) { - "Symbol for ${new.uniqId} was already referenced" + "Symbol for ${new.signature} was already referenced" } - set(uid, new) set(new.descriptor, new) new } } } - private inner class FlatSymbolTable> - : SymbolTableBase() { + private open inner class FlatSymbolTable> : SymbolTableBase() { val descriptorToSymbol = linkedMapOf() - val uniqIdToSymbol = linkedMapOf() + val idSigToSymbol = linkedMapOf() - override fun get(d: D): S? = descriptorToSymbol[d] + protected open fun signature(descriptor: D): IdSignature? = signaturer.composeSignature(descriptor) - override fun set(d: D, s: S) { - descriptorToSymbol[d] = s - } - - override fun get(uid: UniqId): S? = uniqIdToSymbol[uid] - override fun set(uid: UniqId, s: S) { - if (uid != UniqId.NONE) { - uniqIdToSymbol[uid] = s + override fun get(d: D): S? { + return if (d !is WrappedDeclarationDescriptor<*>) { + val sig = signature(d) + if (sig != null) { + idSigToSymbol[sig] + } else { + descriptorToSymbol[d] + } + } else { + descriptorToSymbol[d] } } + + override fun set(d: D, s: S) { + if (s.isPublicApi) { + idSigToSymbol[s.signature] = s + } else { + descriptorToSymbol[d] = s + } + } + + override fun get(sig: IdSignature): S? = idSigToSymbol[sig] + } + + private inner class EnumEntrySymbolTable : FlatSymbolTable() { + override fun signature(descriptor: ClassDescriptor): IdSignature? = signaturer.composeEnumEntrySignature(descriptor) + } + + private inner class FieldSymbolTable : FlatSymbolTable() { + override fun signature(descriptor: PropertyDescriptor): IdSignature? = null } private inner class ScopedSymbolTable> : SymbolTableBase() { inner class Scope(val owner: DeclarationDescriptor, val parent: Scope?) { private val descriptorToSymbol = linkedMapOf() - private val uniqIdToSymbol = linkedMapOf() + private val idSigToSymbol = linkedMapOf() - operator fun get(d: D): S? = - descriptorToSymbol[d] ?: parent?.get(d) + private fun getByDescriptor(d: D): S? { + return descriptorToSymbol[d] ?: parent?.getByDescriptor(d) + } + + private fun getByIdSignature(sig: IdSignature): S? { + return idSigToSymbol[sig] ?: parent?.getByIdSignature(sig) + } + + operator fun get(d: D): S? { + return if (d !is WrappedDeclarationDescriptor<*>) { + val sig = signaturer.composeSignature(d) + if (sig != null) { + getByIdSignature(sig) + } else { + getByDescriptor(d) + } + } else { + getByDescriptor(d) + } + } fun getLocal(d: D) = descriptorToSymbol[d] operator fun set(d: D, s: S) { - descriptorToSymbol[d] = s - } - - operator fun get(uid: UniqId): S? = - uniqIdToSymbol[uid] ?: parent?.get(uid) - - operator fun set(uid: UniqId, s: S) { - if (uid != UniqId.NONE) { - uniqIdToSymbol[uid] = s + if (s.isPublicApi) { + require(d is TypeParameterDescriptor) + idSigToSymbol[s.signature] = s + } else { + descriptorToSymbol[d] = s } } + operator fun get(sig: IdSignature): S? = idSigToSymbol[sig] ?: parent?.get(sig) + fun dumpTo(stringBuilder: StringBuilder): StringBuilder = stringBuilder.also { it.append("owner=") @@ -241,14 +262,9 @@ open class SymbolTable(val mangler: KotlinMangler? = null) : ReferenceSymbolTabl scope[d] = s } - override fun get(uid: UniqId): S? { + override fun get(sig: IdSignature): S? { val scope = currentScope ?: return null - return scope[uid] - } - - override fun set(uid: UniqId, s: S) { - val scope = currentScope ?: throw AssertionError("No active scope") - scope[uid] = s + return scope[sig] } inline fun declareLocal(d: D, createSymbol: () -> S, createOwner: (S) -> B): B { @@ -290,8 +306,8 @@ open class SymbolTable(val mangler: KotlinMangler? = null) : ReferenceSymbolTabl private val scriptSymbolTable = FlatSymbolTable() private val classSymbolTable = FlatSymbolTable() private val constructorSymbolTable = FlatSymbolTable() - private val enumEntrySymbolTable = FlatSymbolTable() - private val fieldSymbolTable = FlatSymbolTable() + private val enumEntrySymbolTable = EnumEntrySymbolTable() + private val fieldSymbolTable = FieldSymbolTable() private val simpleFunctionSymbolTable = FlatSymbolTable() private val propertySymbolTable = FlatSymbolTable() private val typeAliasSymbolTable = FlatSymbolTable() @@ -342,6 +358,10 @@ open class SymbolTable(val mangler: KotlinMangler? = null) : ReferenceSymbolTabl ) } + private fun createClassSymbol(descriptor: ClassDescriptor): IrClassSymbol { + return signaturer.composeSignature(descriptor)?.let { IrClassPublicSymbolImpl(descriptor, it) } ?: IrClassSymbolImpl(descriptor) + } + fun declareClass( startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor, modality: Modality = descriptor.modality, visibility: Visibility = descriptor.visibility, @@ -351,19 +371,51 @@ open class SymbolTable(val mangler: KotlinMangler? = null) : ReferenceSymbolTabl ): IrClass { return classSymbolTable.declare( descriptor, - { IrClassSymbolImpl(descriptor) }, + { createClassSymbol(descriptor) }, classFactory ) } - override fun referenceClass(descriptor: ClassDescriptor) = - classSymbolTable.referenced(descriptor) { IrClassSymbolImpl(descriptor) } + fun declareClassFromLinker(descriptor: ClassDescriptor, sig: IdSignature, factory: (IrClassSymbol) -> IrClass): IrClass { + return classSymbolTable.run { + if (sig.isPublic) { + declare(sig, descriptor, { IrClassPublicSymbolImpl(descriptor, sig) }, factory) + } else { + declare(descriptor, { IrClassSymbolImpl(descriptor) }, factory) + } + } + } - override fun referenceClass(uniqId: UniqId): IrClassSymbol = - classSymbolTable.referenced(uniqId) { IrClassSymbolImpl(uniqId) } + override fun referenceClass(descriptor: ClassDescriptor) = + classSymbolTable.referenced(descriptor) { createClassSymbol(descriptor) } + + private fun createBuiltInClassSymbol(descriptor: ClassDescriptor, sig: IdSignature): IrClassSymbol { + return IrClassPublicSymbolImpl(descriptor, sig) + } + + fun declareBuiltInClass( + descriptor: ClassDescriptor, + mangle: String, + classFactory: (IrClassSymbol) -> IrClass + ): IrClass { + val sig = IdSignature.BuiltInSignature(mangle, signaturer.string2Hash(mangle)) + return classSymbolTable.declare(sig, descriptor, { createBuiltInClassSymbol(descriptor, sig) }, classFactory) + } + + override fun referenceClassFromLinker(descriptor: ClassDescriptor, sig: IdSignature): IrClassSymbol = + classSymbolTable.run { + if (sig.isPublic) referenced(sig) { IrClassPublicSymbolImpl(descriptor, sig) } + else referenced(descriptor) { IrClassSymbolImpl(descriptor) } + } val unboundClasses: Set get() = classSymbolTable.unboundSymbols + private fun createConstructorSymbol(descriptor: ClassConstructorDescriptor): IrConstructorSymbol { + return signaturer.composeSignature(descriptor)?.let { IrConstructorPublicSymbolImpl(descriptor, it) } ?: IrConstructorSymbolImpl( + descriptor + ) + } + fun declareConstructor( startOffset: Int, endOffset: Int, @@ -377,36 +429,79 @@ open class SymbolTable(val mangler: KotlinMangler? = null) : ReferenceSymbolTabl ): IrConstructor = constructorSymbolTable.declare( descriptor, - { IrConstructorSymbolImpl(descriptor) }, + { createConstructorSymbol(descriptor) }, constructorFactory ) override fun referenceConstructor(descriptor: ClassConstructorDescriptor) = - constructorSymbolTable.referenced(descriptor) { IrConstructorSymbolImpl(descriptor) } + constructorSymbolTable.referenced(descriptor) { createConstructorSymbol(descriptor) } - override fun referenceConstructor(uniqId: UniqId): IrConstructorSymbol = - constructorSymbolTable.referenced(uniqId) { IrConstructorSymbolImpl(uniqId) } + fun declareConstructorFromLinker( + descriptor: ClassConstructorDescriptor, + sig: IdSignature, + constructorFactory: (IrConstructorSymbol) -> IrConstructor + ): IrConstructor { + return constructorSymbolTable.run { + if (sig.isPublic) { + declare(sig, descriptor, { IrConstructorPublicSymbolImpl(descriptor, sig) }, constructorFactory) + } else { + declare(descriptor, { IrConstructorSymbolImpl(descriptor) }, constructorFactory) + } + } + } + + override fun referenceConstructorFromLinker(descriptor: ClassConstructorDescriptor, sig: IdSignature): IrConstructorSymbol = + constructorSymbolTable.run { + if (sig.isPublic) referenced(sig) { IrConstructorPublicSymbolImpl(descriptor, sig) } + else referenced(descriptor) { IrConstructorSymbolImpl(descriptor) } + } val unboundConstructors: Set get() = constructorSymbolTable.unboundSymbols + private fun createEnumEntrySymbol(descriptor: ClassDescriptor): IrEnumEntrySymbol { + return signaturer.composeEnumEntrySignature(descriptor)?.let { IrEnumEntryPublicSymbolImpl(descriptor, it) } + ?: IrEnumEntrySymbolImpl(descriptor) + } + fun declareEnumEntry( startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor, factory: (IrEnumEntrySymbol) -> IrEnumEntry = { IrEnumEntryImpl(startOffset, endOffset, origin, it) } ): IrEnumEntry = enumEntrySymbolTable.declare( descriptor, - { IrEnumEntrySymbolImpl(descriptor) }, + { createEnumEntrySymbol(descriptor) }, factory ) - override fun referenceEnumEntry(descriptor: ClassDescriptor) = - enumEntrySymbolTable.referenced(descriptor) { IrEnumEntrySymbolImpl(descriptor) } + fun declareEnumEntryFromLinker( + descriptor: ClassDescriptor, + sig: IdSignature, + factory: (IrEnumEntrySymbol) -> IrEnumEntry + ): IrEnumEntry { + return enumEntrySymbolTable.run { + if (sig.isPublic) { + declare(sig, descriptor, { IrEnumEntryPublicSymbolImpl(descriptor, sig) }, factory) + } else { + declare(descriptor, { IrEnumEntrySymbolImpl(descriptor) }, factory) + } + } + } - override fun referenceEnumEntry(uniqId: UniqId): IrEnumEntrySymbol = - enumEntrySymbolTable.referenced(uniqId) { IrEnumEntrySymbolImpl(uniqId) } + override fun referenceEnumEntry(descriptor: ClassDescriptor) = + enumEntrySymbolTable.referenced(descriptor) { createEnumEntrySymbol(descriptor) } + + override fun referenceEnumEntryFromLinker(descriptor: ClassDescriptor, sig: IdSignature) = + enumEntrySymbolTable.run { + if (sig.isPublic) referenced(sig) { IrEnumEntryPublicSymbolImpl(descriptor, sig) } else + referenced(descriptor) { IrEnumEntrySymbolImpl(descriptor) } + } val unboundEnumEntries: Set get() = enumEntrySymbolTable.unboundSymbols + private fun createFieldSymbol(descriptor: PropertyDescriptor): IrFieldSymbol { + return IrFieldSymbolImpl(descriptor) + } + fun declareField( startOffset: Int, endOffset: Int, @@ -422,7 +517,7 @@ open class SymbolTable(val mangler: KotlinMangler? = null) : ReferenceSymbolTabl ): IrField = fieldSymbolTable.declare( descriptor, - { IrFieldSymbolImpl(descriptor) }, + { createFieldSymbol(descriptor) }, fieldFactory ) @@ -438,11 +533,21 @@ open class SymbolTable(val mangler: KotlinMangler? = null) : ReferenceSymbolTabl initializer = irInitializer } - override fun referenceField(descriptor: PropertyDescriptor) = - fieldSymbolTable.referenced(descriptor) { IrFieldSymbolImpl(descriptor) } + fun declareFieldFromLinker(descriptor: PropertyDescriptor, sig: IdSignature, factory: (IrFieldSymbol) -> IrField): IrField { + return fieldSymbolTable.run { + require(sig.isLocal) + declare(descriptor, { IrFieldSymbolImpl(descriptor) }, factory) + } + } - override fun referenceField(uniqId: UniqId) = - fieldSymbolTable.referenced(uniqId) { IrFieldSymbolImpl(uniqId) } + override fun referenceField(descriptor: PropertyDescriptor) = + fieldSymbolTable.referenced(descriptor) { createFieldSymbol(descriptor) } + + override fun referenceFieldFromLinker(descriptor: PropertyDescriptor, sig: IdSignature) = + fieldSymbolTable.run { + require(sig.isLocal) + referenced(descriptor) { IrFieldSymbolImpl(descriptor) } + } val unboundFields: Set get() = fieldSymbolTable.unboundSymbols @@ -452,6 +557,13 @@ open class SymbolTable(val mangler: KotlinMangler? = null) : ReferenceSymbolTabl override fun referenceProperty(descriptor: PropertyDescriptor, generate: () -> IrProperty): IrProperty = propertyTable.getOrPut(descriptor, generate) + private fun createPropertySymbol(descriptor: PropertyDescriptor): IrPropertySymbol { + return signaturer.composeSignature(descriptor)?.let { IrPropertyPublicSymbolImpl(descriptor, it) } ?: IrPropertySymbolImpl( + descriptor + ) + + } + fun declareProperty( startOffset: Int, endOffset: Int, @@ -466,29 +578,70 @@ open class SymbolTable(val mangler: KotlinMangler? = null) : ReferenceSymbolTabl ): IrProperty = propertySymbolTable.declare( descriptor, - { IrPropertySymbolImpl(descriptor) }, + { createPropertySymbol(descriptor) }, propertyFactory ) - fun referenceProperty(descriptor: PropertyDescriptor): IrPropertySymbol = - propertySymbolTable.referenced(descriptor) { IrPropertySymbolImpl(descriptor) } + fun declarePropertyFromLinker(descriptor: PropertyDescriptor, sig: IdSignature, factory: (IrPropertySymbol) -> IrProperty): IrProperty { + return propertySymbolTable.run { + if (sig.isPublic) { + declare(sig, descriptor, { IrPropertyPublicSymbolImpl(descriptor, sig) }, factory) + } else { + declare(descriptor, { IrPropertySymbolImpl(descriptor) }, factory) + } + } + } - override fun referenceProperty(uniqId: UniqId): IrPropertySymbol = - propertySymbolTable.referenced(uniqId) { IrPropertySymbolImpl(uniqId) } + fun referenceProperty(descriptor: PropertyDescriptor): IrPropertySymbol = + propertySymbolTable.referenced(descriptor) { createPropertySymbol(descriptor) } + + override fun referencePropertyFromLinker(descriptor: PropertyDescriptor, sig: IdSignature): IrPropertySymbol = + propertySymbolTable.run { + if (sig.isPublic) referenced(sig) { IrPropertyPublicSymbolImpl(descriptor, sig) } + else referenced(descriptor) { IrPropertySymbolImpl(descriptor) } + } val unboundProperties: Set get() = propertySymbolTable.unboundSymbols - override fun referenceTypeAlias(descriptor: TypeAliasDescriptor): IrTypeAliasSymbol = - typeAliasSymbolTable.referenced(descriptor) { IrTypeAliasSymbolImpl(descriptor) } + private fun createTypeAliasSymbol(descriptor: TypeAliasDescriptor): IrTypeAliasSymbol { + return signaturer.composeSignature(descriptor)?.let { IrTypeAliasPublicSymbolImpl(descriptor, it) } ?: IrTypeAliasSymbolImpl( + descriptor + ) + } - override fun referenceTypeAlias(uniqId: UniqId): IrTypeAliasSymbol = - typeAliasSymbolTable.referenced(uniqId) { IrTypeAliasSymbolImpl(uniqId) } + override fun referenceTypeAlias(descriptor: TypeAliasDescriptor): IrTypeAliasSymbol = + typeAliasSymbolTable.referenced(descriptor) { createTypeAliasSymbol(descriptor) } + + fun declareTypeAliasFromLinker( + descriptor: TypeAliasDescriptor, + sig: IdSignature, + factory: (IrTypeAliasSymbol) -> IrTypeAlias + ): IrTypeAlias { + return typeAliasSymbolTable.run { + if (sig.isPublic) { + declare(sig, descriptor, { IrTypeAliasPublicSymbolImpl(descriptor, sig) }, factory) + } else { + declare(descriptor, { IrTypeAliasSymbolImpl(descriptor) }, factory) + } + } + } + + override fun referenceTypeAliasFromLinker(descriptor: TypeAliasDescriptor, sig: IdSignature) = + typeAliasSymbolTable.run { + if (sig.isPublic) referenced(sig) { IrTypeAliasPublicSymbolImpl(descriptor, sig) } else + referenced(descriptor) { IrTypeAliasSymbolImpl(descriptor) } + } fun declareTypeAlias(descriptor: TypeAliasDescriptor, factory: (IrTypeAliasSymbol) -> IrTypeAlias): IrTypeAlias = - typeAliasSymbolTable.declare(descriptor, { IrTypeAliasSymbolImpl(descriptor) }, factory) + typeAliasSymbolTable.declare(descriptor, { createTypeAliasSymbol(descriptor) }, factory) val unboundTypeAliases: Set get() = typeAliasSymbolTable.unboundSymbols + private fun createSimpleFunctionSymbol(descriptor: FunctionDescriptor): IrSimpleFunctionSymbol { + return signaturer.composeSignature(descriptor)?.let { IrSimpleFunctionPublicSymbolImpl(descriptor, it) } + ?: IrSimpleFunctionSymbolImpl(descriptor) + } + fun declareSimpleFunction( startOffset: Int, endOffset: Int, @@ -502,22 +655,67 @@ open class SymbolTable(val mangler: KotlinMangler? = null) : ReferenceSymbolTabl ): IrSimpleFunction { return simpleFunctionSymbolTable.declare( descriptor, - { IrSimpleFunctionSymbolImpl(descriptor) }, + { createSimpleFunctionSymbol(descriptor) }, functionFactory ) } - override fun referenceSimpleFunction(descriptor: FunctionDescriptor) = - simpleFunctionSymbolTable.referenced(descriptor) { IrSimpleFunctionSymbolImpl(descriptor) } + fun declareSimpleFunctionFromLinker( + descriptor: FunctionDescriptor, + sig: IdSignature, + functionFactory: (IrSimpleFunctionSymbol) -> IrSimpleFunction + ): IrSimpleFunction { + return simpleFunctionSymbolTable.run { + if (sig.isPublic) { + declare(sig, descriptor, { IrSimpleFunctionPublicSymbolImpl(descriptor, sig) }, functionFactory) + } else { + declare(descriptor, { IrSimpleFunctionSymbolImpl(descriptor) }, functionFactory) + } + } + } - override fun referenceSimpleFunction(uniqId: UniqId): IrSimpleFunctionSymbol = - simpleFunctionSymbolTable.referenced(uniqId) { IrSimpleFunctionSymbolImpl(uniqId) } + private fun createBuiltInOperatorSymbol(descriptor: FunctionDescriptor, sig: IdSignature): IrSimpleFunctionSymbol { + return IrSimpleFunctionPublicSymbolImpl(descriptor, sig) + } + + fun declareBuiltInOperator( + descriptor: FunctionDescriptor, + mangle: String, + functionFactory: (IrSimpleFunctionSymbol) -> IrSimpleFunction + ): IrSimpleFunction { + val sig = IdSignature.BuiltInSignature(mangle, signaturer.string2Hash(mangle)) + return simpleFunctionSymbolTable.declare( + sig, + descriptor, + { createBuiltInOperatorSymbol(descriptor, sig) }, + functionFactory + ) + } + + fun referenceBuiltInOperator(descriptor: FunctionDescriptor, mangle: String): IrSimpleFunctionSymbol { + val sig = IdSignature.BuiltInSignature(mangle, signaturer.string2Hash(mangle)) + return simpleFunctionSymbolTable.referenced(sig) { createBuiltInOperatorSymbol(descriptor, sig) } + } + + override fun referenceSimpleFunction(descriptor: FunctionDescriptor) = + simpleFunctionSymbolTable.referenced(descriptor) { createSimpleFunctionSymbol(descriptor) } + + override fun referenceSimpleFunctionFromLinker(descriptor: FunctionDescriptor, sig: IdSignature): IrSimpleFunctionSymbol { + return simpleFunctionSymbolTable.run { + if (sig.isPublic) referenced(sig) { IrSimpleFunctionPublicSymbolImpl(descriptor, sig) } else + referenced(descriptor) { IrSimpleFunctionSymbolImpl(descriptor) } + } + } override fun referenceDeclaredFunction(descriptor: FunctionDescriptor) = simpleFunctionSymbolTable.referenced(descriptor) { throw AssertionError("Function is not declared: $descriptor") } val unboundSimpleFunctions: Set get() = simpleFunctionSymbolTable.unboundSymbols + private fun createTypeParameterSymbol(descriptor: TypeParameterDescriptor): IrTypeParameterSymbol { + return IrTypeParameterSymbolImpl(descriptor) + } + fun declareGlobalTypeParameter( startOffset: Int, endOffset: Int, @@ -527,10 +725,19 @@ open class SymbolTable(val mangler: KotlinMangler? = null) : ReferenceSymbolTabl ): IrTypeParameter = globalTypeParameterSymbolTable.declare( descriptor, - { IrTypeParameterSymbolImpl(descriptor) }, + { createTypeParameterSymbol(descriptor) }, typeParameterFactory ) + fun declareGlobalTypeParameterFromLinker( + descriptor: TypeParameterDescriptor, + sig: IdSignature, + typeParameterFactory: (IrTypeParameterSymbol) -> IrTypeParameter + ): IrTypeParameter { + require(sig.isLocal) + return globalTypeParameterSymbolTable.declare(descriptor, { IrTypeParameterSymbolImpl(descriptor) }, typeParameterFactory) + } + fun declareScopedTypeParameter( startOffset: Int, endOffset: Int, @@ -540,10 +747,18 @@ open class SymbolTable(val mangler: KotlinMangler? = null) : ReferenceSymbolTabl ): IrTypeParameter = scopedTypeParameterSymbolTable.declare( descriptor, - { IrTypeParameterSymbolImpl(descriptor) }, + { createTypeParameterSymbol(descriptor) }, typeParameterFactory ) + fun declareScopedTypeParameterFromLinker( + descriptor: TypeParameterDescriptor, + sig: IdSignature, + typeParameterFactory: (IrTypeParameterSymbol) -> IrTypeParameter + ): IrTypeParameter { + require(sig.isLocal) + return scopedTypeParameterSymbolTable.declare(descriptor, { IrTypeParameterSymbolImpl(descriptor) }, typeParameterFactory) + } val unboundTypeParameters: Set get() = globalTypeParameterSymbolTable.unboundSymbols @@ -575,13 +790,14 @@ open class SymbolTable(val mangler: KotlinMangler? = null) : ReferenceSymbolTabl override fun referenceTypeParameter(classifier: TypeParameterDescriptor): IrTypeParameterSymbol = scopedTypeParameterSymbolTable.get(classifier) ?: globalTypeParameterSymbolTable.referenced(classifier) { - IrTypeParameterSymbolImpl(classifier) + createTypeParameterSymbol(classifier) } - override fun referenceTypeParameter(uniqId: UniqId): IrTypeParameterSymbol = - scopedTypeParameterSymbolTable.get(uniqId) ?: globalTypeParameterSymbolTable.referenced(uniqId) { - IrTypeParameterSymbolImpl(uniqId) - } + override fun referenceTypeParameterFromLinker(classifier: TypeParameterDescriptor, sig: IdSignature): IrTypeParameterSymbol { + require(sig.isLocal) + return scopedTypeParameterSymbolTable.get(classifier) + ?: globalTypeParameterSymbolTable.referenced(classifier) { IrTypeParameterSymbolImpl(classifier) } + } fun declareVariable( startOffset: Int, @@ -650,44 +866,11 @@ open class SymbolTable(val mangler: KotlinMangler? = null) : ReferenceSymbolTabl else -> throw IllegalArgumentException("Unexpected value descriptor: $value") } - - override fun computeUniqId(declaration: IrDeclaration) { - if (mangler == null) return - with(mangler) { - if (!declaration.isExported()) return - } - when(declaration) { - is IrConstructor -> constructorSymbolTable.computeUniqId(declaration) - is IrClass -> classSymbolTable.computeUniqId(declaration) - is IrEnumEntry -> enumEntrySymbolTable.computeUniqId(declaration) - is IrField -> fieldSymbolTable.computeUniqId(declaration) - is IrProperty -> propertySymbolTable.computeUniqId(declaration) - is IrSimpleFunction -> simpleFunctionSymbolTable.computeUniqId(declaration) - is IrTypeAlias -> typeAliasSymbolTable.computeUniqId(declaration) - is IrTypeParameter -> globalTypeParameterSymbolTable.computeUniqId(declaration) - else -> { /* do nothing */ } - } - } } -inline fun SymbolTable.withScope(owner: D, block: SymbolTable.(D) -> T): T { +inline fun SymbolTable.withScope(owner: D, block: SymbolTable.(D) -> T): T { enterScope(owner) val result = block(owner) leaveScope(owner) return result -} - -fun IrElement.computeUniqIdForDeclarations(symbolTable: SymbolTable) { - acceptVoid(ComputeUniqIdVisitor(symbolTable)) -} - -private class ComputeUniqIdVisitor(val symbolTable: SymbolTable) : IrElementVisitorVoid { - override fun visitElement(element: IrElement) { - element.acceptChildrenVoid(this) - } - - override fun visitDeclaration(declaration: IrDeclaration) { - symbolTable.computeUniqId(declaration) - super.visitDeclaration(declaration) - } -} +} \ No newline at end of file diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt index 86330e3cb97..0fe14cb9b99 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt @@ -200,7 +200,9 @@ fun loadIr( } is MainModule.Klib -> { val moduleDescriptor = depsDescriptors.getModuleDescriptor(mainModule.lib) - val symbolTable = SymbolTable() + val mangler = JsManglerDesc + val signaturer = IdSignatureDescriptor(mangler) + val symbolTable = SymbolTable(signaturer) val constantValueGenerator = ConstantValueGenerator(moduleDescriptor, symbolTable) val typeTranslator = TypeTranslator( symbolTable, @@ -209,8 +211,8 @@ fun loadIr( ) typeTranslator.constantValueGenerator = constantValueGenerator constantValueGenerator.typeTranslator = typeTranslator - val irBuiltIns = IrBuiltIns(moduleDescriptor.builtIns, typeTranslator, symbolTable) - val deserializer = JsIrLinker(moduleDescriptor, JsMangler, emptyLoggingContext, irBuiltIns, symbolTable) + val irBuiltIns = IrBuiltIns(moduleDescriptor.builtIns, typeTranslator, signaturer, symbolTable) + val deserializer = JsIrLinker(emptyLoggingContext, irBuiltIns, symbolTable) val deserializedModuleFragments = sortDependencies(allDependencies.getFullList(), depsDescriptors.descriptors).map { val strategy = @@ -234,14 +236,17 @@ fun loadIr( private fun runAnalysisAndPreparePsi2Ir(depsDescriptors: ModulesStructure): GeneratorContext { val analysisResult = depsDescriptors.runAnalysis() + val mangler = JsManglerDesc + val signaturer = IdSignatureDescriptor(mangler) return GeneratorContext( Psi2IrConfiguration(), analysisResult.moduleDescriptor, analysisResult.bindingContext, depsDescriptors.compilerConfiguration.languageVersionSettings, - SymbolTable(), - JsGeneratorExtensions() + SymbolTable(signaturer), + GeneratorExtensions(), + signaturer ) } @@ -252,7 +257,8 @@ fun GeneratorContext.generateModuleFragmentWithPlugins( expectDescriptorToSymbol: MutableMap? = null ): IrModuleFragment { val irProviders = generateTypicalIrProviderList(moduleDescriptor, irBuiltIns, symbolTable, deserializer) - val psi2Ir = Psi2IrTranslator(languageVersionSettings, configuration, mangler = JsMangler) + val signaturer = IdSignatureDescriptor(JsManglerDesc) + val psi2Ir = Psi2IrTranslator(languageVersionSettings, configuration, signaturer) for (extension in IrGenerationExtension.getInstances(project)) { psi2Ir.addPostprocessingStep { module -> @@ -282,8 +288,10 @@ fun GeneratorContext.generateModuleFragmentWithPlugins( fun GeneratorContext.generateModuleFragment(files: List, deserializer: IrDeserializer? = null, expectDescriptorToSymbol: MutableMap? = null): IrModuleFragment { val irProviders = generateTypicalIrProviderList(moduleDescriptor, irBuiltIns, symbolTable, deserializer) + val mangler = JsManglerDesc + val signaturer = IdSignatureDescriptor(mangler) return Psi2IrTranslator( - languageVersionSettings, configuration, mangler = JsMangler + languageVersionSettings, configuration, signaturer ).generateModuleFragment(this, files, irProviders, expectDescriptorToSymbol) } diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/GenerationUtils.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/GenerationUtils.kt index d204f852e4d..f192fe6898a 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/GenerationUtils.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/codegen/GenerationUtils.kt @@ -24,8 +24,10 @@ import com.intellij.psi.search.ProjectScope import org.jetbrains.kotlin.TestsCompiletimeError import org.jetbrains.kotlin.asJava.finder.JavaElementFinder import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig +import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory import org.jetbrains.kotlin.backend.jvm.jvmPhases +import org.jetbrains.kotlin.backend.jvm.serialization.JvmManglerDesc import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.cli.common.output.writeAllTo @@ -136,7 +138,7 @@ object GenerationUtils { } } val (moduleFragment, symbolTable, sourceManager) = - Fir2IrConverter.createModuleFragment(session, firFiles, configuration.languageVersionSettings) + Fir2IrConverter.createModuleFragment(session, firFiles, configuration.languageVersionSettings, signaturer = IdSignatureDescriptor(JvmManglerDesc())) val dummyBindingContext = NoScopeRecordCliBindingTrace().bindingContext val codegenFactory = JvmIrCodegenFactory(configuration.get(CLIConfigurationKeys.PHASE_CONFIG) ?: PhaseConfig(jvmPhases)) diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractIrGeneratorTestCase.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractIrGeneratorTestCase.kt index 2a9176e9e10..12a57632ea4 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractIrGeneratorTestCase.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractIrGeneratorTestCase.kt @@ -17,12 +17,13 @@ package org.jetbrains.kotlin.ir import org.jetbrains.kotlin.analyzer.AnalysisResult +import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensions import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.codegen.CodegenTestCase import org.jetbrains.kotlin.config.languageVersionSettings -import org.jetbrains.kotlin.ir.backend.js.JsGeneratorExtensions +import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerDesc import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS @@ -84,7 +85,11 @@ abstract class AbstractIrGeneratorTestCase : CodegenTestCase() { protected open fun generateIrModule(ignoreErrors: Boolean = false): IrModuleFragment { assert(myFiles != null) { "myFiles not initialized" } assert(myEnvironment != null) { "myEnvironment not initialized" } - return doGenerateIrModule(Psi2IrTranslator(myEnvironment.configuration.languageVersionSettings, Psi2IrConfiguration(ignoreErrors))) + val mangler = JsManglerDesc + val signaturer = IdSignatureDescriptor(mangler) + return doGenerateIrModule(Psi2IrTranslator(myEnvironment.configuration.languageVersionSettings, + Psi2IrConfiguration(ignoreErrors), + signaturer)) } protected open fun doGenerateIrModule(psi2IrTranslator: Psi2IrTranslator): IrModuleFragment = @@ -111,7 +116,7 @@ abstract class AbstractIrGeneratorTestCase : CodegenTestCase() { moduleDescriptors = emptyList(), friendModuleDescriptors = emptyList() ), - psi2ir, ktFilesToAnalyze, JsGeneratorExtensions() + psi2ir, ktFilesToAnalyze, GeneratorExtensions() ) fun generateIrModuleWithJvmResolve( diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractIrTextTestCase.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractIrTextTestCase.kt index 7aa0438b7ae..8785dda9fea 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractIrTextTestCase.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractIrTextTestCase.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.ir import com.intellij.openapi.util.text.StringUtil import junit.framework.TestCase +import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor import org.jetbrains.kotlin.cli.js.loadPluginsForTests import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.languageVersionSettings @@ -25,6 +26,7 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies +import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerDesc import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.symbols.IrSymbol @@ -61,10 +63,12 @@ abstract class AbstractIrTextTestCase : AbstractIrGeneratorTestCase() { private fun doTestIrModuleDependencies(wholeFile: File, irModule: IrModuleFragment) { val wholeText = wholeFile.readText() + val mangler = JsManglerDesc + val signaturer = IdSignatureDescriptor(mangler) val stubGenerator = DeclarationStubGenerator( irModule.descriptor, - SymbolTable(), // TODO + SymbolTable(signaturer), // TODO myEnvironment.configuration.languageVersionSettings ) diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/ScriptJsCompilerImpls.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/ScriptJsCompilerImpls.kt index 5b35b73c0f8..e503e63ff10 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/ScriptJsCompilerImpls.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/ScriptJsCompilerImpls.kt @@ -5,10 +5,12 @@ package org.jetbrains.kotlin.scripting.compiler.plugin.impl +import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.cli.common.repl.ReplCompileResult import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.descriptors.ModuleDescriptor +import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerDesc import org.jetbrains.kotlin.ir.backend.js.utils.NameTables import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.scripting.compiler.plugin.ScriptCompilerProxy @@ -20,7 +22,7 @@ import kotlin.script.experimental.api.* class JsScriptCompilerWithDependenciesProxy(private val environment: KotlinCoreEnvironment) : ScriptCompilerProxy { private val nameTables = NameTables(emptyList()) - private val symbolTable = SymbolTable() + private val symbolTable = SymbolTable(IdSignatureDescriptor(JsManglerDesc)) private val dependencies: List = readLibrariesFromConfiguration(environment.configuration) private val compiler = JsCoreScriptingCompiler(environment, nameTables, symbolTable, dependencies) private var scriptDependencyCompiler: JsScriptDependencyCompiler? = diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/repl/js/JsCoreScriptingCompiler.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/repl/js/JsCoreScriptingCompiler.kt index 6865b79dc97..cf4bcabba8e 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/repl/js/JsCoreScriptingCompiler.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/repl/js/JsCoreScriptingCompiler.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.scripting.repl.js +import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.cli.common.environment.setIdeaIoUseFallback import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport @@ -18,7 +19,7 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext import org.jetbrains.kotlin.ir.backend.js.generateJsCode import org.jetbrains.kotlin.ir.backend.js.generateModuleFragment -import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsMangler +import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerDesc import org.jetbrains.kotlin.ir.backend.js.utils.NameTables import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator import org.jetbrains.kotlin.ir.util.SymbolTable @@ -59,8 +60,9 @@ class JsCoreScriptingCompiler( val module = analysisResult.moduleDescriptor val bindingContext = analysisResult.bindingContext - - val psi2ir = Psi2IrTranslator(environment.configuration.languageVersionSettings, mangler = JsMangler) + val mangler = JsManglerDesc + val signaturer = IdSignatureDescriptor(mangler) + val psi2ir = Psi2IrTranslator(environment.configuration.languageVersionSettings, signaturer = signaturer) val psi2irContext = psi2ir.createGeneratorContext(module, bindingContext, symbolTable) val irModuleFragment = psi2irContext.generateModuleFragment(listOf(snippetKtFile)) diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/repl/js/JsReplCompiler.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/repl/js/JsReplCompiler.kt index ef7a7399fef..3d55a39be6e 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/repl/js/JsReplCompiler.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/repl/js/JsReplCompiler.kt @@ -5,8 +5,10 @@ package org.jetbrains.kotlin.scripting.repl.js +import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor import org.jetbrains.kotlin.cli.common.repl.* import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment +import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerDesc import org.jetbrains.kotlin.ir.backend.js.utils.NameTables import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.scripting.compiler.plugin.repl.ReplCodeAnalyzer @@ -21,7 +23,7 @@ class JsReplCompiler(private val environment: KotlinCoreEnvironment) : ReplCompi NameTables(emptyList()), readLibrariesFromConfiguration(environment.configuration), ReplCodeAnalyzer.ResettableAnalyzerState(), - SymbolTable() + SymbolTable(IdSignatureDescriptor(JsManglerDesc)) ) } diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/repl/js/JsScriptDependencyCompiler.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/repl/js/JsScriptDependencyCompiler.kt index bc34af15e37..a3c205636a3 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/repl/js/JsScriptDependencyCompiler.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/repl/js/JsScriptDependencyCompiler.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.scripting.repl.js +import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl @@ -15,7 +16,7 @@ import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext import org.jetbrains.kotlin.ir.backend.js.emptyLoggingContext import org.jetbrains.kotlin.ir.backend.js.generateJsCode import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker -import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsMangler +import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerDesc import org.jetbrains.kotlin.ir.backend.js.utils.NameTables import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns @@ -45,8 +46,9 @@ class JsScriptDependencyCompiler( it.constantValueGenerator = ConstantValueGenerator(moduleDescriptor, symbolTable) } - val irBuiltIns = IrBuiltIns(builtIns, typeTranslator, symbolTable) - val jsLinker = JsIrLinker(moduleDescriptor, JsMangler, emptyLoggingContext, irBuiltIns, symbolTable) + val signaturer = IdSignatureDescriptor(JsManglerDesc) + val irBuiltIns = IrBuiltIns(builtIns, typeTranslator, signaturer, symbolTable) + val jsLinker = JsIrLinker(emptyLoggingContext, irBuiltIns, symbolTable) val moduleFragment = IrModuleFragmentImpl(moduleDescriptor, irBuiltIns) val irDependencies = dependencies.map { jsLinker.deserializeFullModule(it) }